[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

newb) converting seconds into plain english time units

luke

7/6/2005 5:07:00 AM

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



4 Answers

Robert Klemme

7/6/2005 6:46:00 AM

0

luke <lduncalfe@eml.nope> 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

daz

7/6/2005 9:14:00 AM

0


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


luke

7/7/2005 2:22:00 AM

0


thanks to you both, that works a charm :)



"daz" <dooby@d10.karoo.co.uk> wrote in message
news:55mcnc4beoS7PFbfSa8jmw@karoo.co.uk...
>
> 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
>
>


Gene Tani

7/7/2005 3:12:00 AM

0

check out ActiveSupport::CoreExtensions::Time::Calculations
also ActiveSupport::CoreExtensions::String::Inflections

http://as.rubyon...


luke wrote:
> thanks to you both, that works a charm :)
>
>
>
> "daz" <dooby@d10.karoo.co.uk> wrote in message
> news:55mcnc4beoS7PFbfSa8jmw@karoo.co.uk...
> >
> > 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
> >
> >