Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > (newb) converting seconds into plain english time units

Reply
Thread Tools

(newb) converting seconds into plain english time units

 
 
luke
Guest
Posts: n/a
 
      07-06-2005
hi,

i'm having some difficulty in writing a method that takes a number of
seconds, and returns the equivalent in hours, days, or weeks depending on
which time unit is most appropriate.

the part that's not working is that i want the code to know if it should use
a plural or not, so for it to return "day" if there is only one, and "days"
if there are more, for example. except at the moment it's making everything
a plural!

this is the code, apologies if it is offensive to the eye:

def format_time seconds
hours = (seconds / (60 * 60))
plural = "s" if hours.to_i > 1
time = "#{hours.to_i} hour#{plural}"
if hours > 23
days = hours / 24
plural = "s" if days.to_i > 1
time = "#{days.to_i} day#{plural}"
if days > 30
weeks = days / 7
plural = "s" if weeks.to_i > 1
time = "#{weeks.to_i} week#{plural}"
end
end

time
end


and i've got a suspicion some of this would be better with the use of
'yield' and blocks, except i've thoroughly messed those up as well!

any help would be much appreciated.

thanks
luke



 
Reply With Quote
 
 
 
 
Robert Klemme
Guest
Posts: n/a
 
      07-06-2005
luke <(E-Mail Removed)> wrote:
> hi,
>
> i'm having some difficulty in writing a method that takes a number of
> seconds, and returns the equivalent in hours, days, or weeks
> depending on which time unit is most appropriate.
>
> the part that's not working is that i want the code to know if it
> should use a plural or not, so for it to return "day" if there is
> only one, and "days" if there are more, for example. except at the
> moment it's making everything a plural!
>
> this is the code, apologies if it is offensive to the eye:
>
> def format_time seconds
> hours = (seconds / (60 * 60))
> plural = "s" if hours.to_i > 1
> time = "#{hours.to_i} hour#{plural}"
> if hours > 23
> days = hours / 24
> plural = "s" if days.to_i > 1
> time = "#{days.to_i} day#{plural}"
> if days > 30
> weeks = days / 7
> plural = "s" if weeks.to_i > 1
> time = "#{weeks.to_i} week#{plural}"
> end
> end
>
> time
> end
>
>
> and i've got a suspicion some of this would be better with the use of
> 'yield' and blocks, except i've thoroughly messed those up as well!
>
> any help would be much appreciated.
>
> thanks
> luke


The way I did this once was to have two arrays, one containing factors and
the other containing corresponding unit names. That way the transformation
really becomes a loop - and it's easy to adapt. For example, you can have
another array with unit names for amount of 1. Or you create a hash from
amont to unit names with a default for multiple thus giving you even more
flexibility.

Kind regards

robert

 
Reply With Quote
 
 
 
 
daz
Guest
Posts: n/a
 
      07-06-2005

luke wrote:
> hi,
>
> [...] at the moment it's making everything a plural!
>
>
> def format_time seconds
> hours = (seconds / (60 * 60))
> plural = "s" if hours.to_i > 1
> time = "#{hours.to_i} hour#{plural}"
> if hours > 23
> days = hours / 24
> plural = "s" if days.to_i > 1
> time = "#{days.to_i} day#{plural}"
> if days > 30
> weeks = days / 7
> plural = "s" if weeks.to_i > 1
> time = "#{weeks.to_i} week#{plural}"
> end
> end
>
> time
> end
>
> [...]
>
> any help would be much appreciated.
>


The reason you're getting plural is that
"plural" is only set to 's', never ''.

Here's one way which is probably similar to the way
Robert was describing.
(Haven't checked it rigorously

#----------------------------------------------------
def format_time(seconds)
arr = [ ['second', [3600] ],
['hour', [24] ],
['day', [31, 7] ],
['week', nil ],
]
t = seconds
aix = 0
while (lim = arr[aix][1])
## ternary operator cond ? true : false
(t >= lim[0]) ? t /= lim[-1] : break
aix += 1
end
## % is a method of the String class (like sprintf)
'%4d %s%s' % [t, arr[aix][0], (t == 1) ? '' : 's']
end

[ 0, #-> 0 seconds
1, #-> 1 second
36, #-> 36 seconds
3599, #-> 3599 seconds
3600, #-> 1 hour
3601, #-> 1 hour
3600*4, #-> 4 hours
3600*23, #-> 23 hours
3600*24*2, #-> 2 days
3600*24*7, #-> 7 days
3600*24*30, #-> 30 days
3600*24*31, #-> 4 weeks
3600*24*32, #-> 4 weeks
3600*24*60, #-> 8 weeks
3600*24*100, #-> 14 weeks
].each do |secs|
puts format_time(secs)
end
#----------------------------------------------------

daz


 
Reply With Quote
 
luke
Guest
Posts: n/a
 
      07-07-2005

thanks to you both, that works a charm



"daz" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
>
> luke wrote:
> > hi,
> >
> > [...] at the moment it's making everything a plural!
> >
> >
> > def format_time seconds
> > hours = (seconds / (60 * 60))
> > plural = "s" if hours.to_i > 1
> > time = "#{hours.to_i} hour#{plural}"
> > if hours > 23
> > days = hours / 24
> > plural = "s" if days.to_i > 1
> > time = "#{days.to_i} day#{plural}"
> > if days > 30
> > weeks = days / 7
> > plural = "s" if weeks.to_i > 1
> > time = "#{weeks.to_i} week#{plural}"
> > end
> > end
> >
> > time
> > end
> >
> > [...]
> >
> > any help would be much appreciated.
> >

>
> The reason you're getting plural is that
> "plural" is only set to 's', never ''.
>
> Here's one way which is probably similar to the way
> Robert was describing.
> (Haven't checked it rigorously
>
> #----------------------------------------------------
> def format_time(seconds)
> arr = [ ['second', [3600] ],
> ['hour', [24] ],
> ['day', [31, 7] ],
> ['week', nil ],
> ]
> t = seconds
> aix = 0
> while (lim = arr[aix][1])
> ## ternary operator cond ? true : false
> (t >= lim[0]) ? t /= lim[-1] : break
> aix += 1
> end
> ## % is a method of the String class (like sprintf)
> '%4d %s%s' % [t, arr[aix][0], (t == 1) ? '' : 's']
> end
>
> [ 0, #-> 0 seconds
> 1, #-> 1 second
> 36, #-> 36 seconds
> 3599, #-> 3599 seconds
> 3600, #-> 1 hour
> 3601, #-> 1 hour
> 3600*4, #-> 4 hours
> 3600*23, #-> 23 hours
> 3600*24*2, #-> 2 days
> 3600*24*7, #-> 7 days
> 3600*24*30, #-> 30 days
> 3600*24*31, #-> 4 weeks
> 3600*24*32, #-> 4 weeks
> 3600*24*60, #-> 8 weeks
> 3600*24*100, #-> 14 weeks
> ].each do |secs|
> puts format_time(secs)
> end
> #----------------------------------------------------
>
> daz
>
>



 
Reply With Quote
 
Gene Tani
Guest
Posts: n/a
 
      07-07-2005
check out ActiveSupport::CoreExtensions::Time::Calculations
also ActiveSupport::CoreExtensions::String::Inflections

http://as.rubyonrails.com/


luke wrote:
> thanks to you both, that works a charm
>
>
>
> "daz" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
> >
> > luke wrote:
> > > hi,
> > >
> > > [...] at the moment it's making everything a plural!
> > >
> > >
> > > def format_time seconds
> > > hours = (seconds / (60 * 60))
> > > plural = "s" if hours.to_i > 1
> > > time = "#{hours.to_i} hour#{plural}"
> > > if hours > 23
> > > days = hours / 24
> > > plural = "s" if days.to_i > 1
> > > time = "#{days.to_i} day#{plural}"
> > > if days > 30
> > > weeks = days / 7
> > > plural = "s" if weeks.to_i > 1
> > > time = "#{weeks.to_i} week#{plural}"
> > > end
> > > end
> > >
> > > time
> > > end
> > >
> > > [...]
> > >
> > > any help would be much appreciated.
> > >

> >
> > The reason you're getting plural is that
> > "plural" is only set to 's', never ''.
> >
> > Here's one way which is probably similar to the way
> > Robert was describing.
> > (Haven't checked it rigorously
> >
> > #----------------------------------------------------
> > def format_time(seconds)
> > arr = [ ['second', [3600] ],
> > ['hour', [24] ],
> > ['day', [31, 7] ],
> > ['week', nil ],
> > ]
> > t = seconds
> > aix = 0
> > while (lim = arr[aix][1])
> > ## ternary operator cond ? true : false
> > (t >= lim[0]) ? t /= lim[-1] : break
> > aix += 1
> > end
> > ## % is a method of the String class (like sprintf)
> > '%4d %s%s' % [t, arr[aix][0], (t == 1) ? '' : 's']
> > end
> >
> > [ 0, #-> 0 seconds
> > 1, #-> 1 second
> > 36, #-> 36 seconds
> > 3599, #-> 3599 seconds
> > 3600, #-> 1 hour
> > 3601, #-> 1 hour
> > 3600*4, #-> 4 hours
> > 3600*23, #-> 23 hours
> > 3600*24*2, #-> 2 days
> > 3600*24*7, #-> 7 days
> > 3600*24*30, #-> 30 days
> > 3600*24*31, #-> 4 weeks
> > 3600*24*32, #-> 4 weeks
> > 3600*24*60, #-> 8 weeks
> > 3600*24*100, #-> 14 weeks
> > ].each do |secs|
> > puts format_time(secs)
> > end
> > #----------------------------------------------------
> >
> > daz
> >
> >


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
How to convert Seconds to X Hours Y Minutes Z Seconds? 00_CP_D12 ASP .Net 3 02-22-2008 10:37 AM
1. Ruby result: 101 seconds , 2. Java result:9.8 seconds, 3. Perl result:62 seconds Michael Tan Ruby 32 07-21-2005 03:23 PM
Convert seconds to minutes and seconds tshad ASP .Net 7 03-11-2005 11:27 PM
Converting seconds to (Days, Hours, Minutes, seconds) Stu C Programming 7 03-07-2005 08:44 AM
Content from a memo field: converting the rich text into plain text Alfredo Agosti ASP General 3 09-19-2003 05:01 PM



Advertisments