(newb) converting seconds into plain english time units

L

luke

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
 
R

Robert Klemme

luke said:
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
 
D

daz

luke said:
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
 
L

luke

thanks to you both, that works a charm :)



daz said:
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
 
G

Gene Tani

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

http://as.rubyonrails.com/

thanks to you both, that works a charm :)



daz said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,775
Messages
2,569,601
Members
45,182
Latest member
alexanderrm

Latest Threads

Top