(newb) converting seconds into plain english time units

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: :slight_smile:

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

···

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: :slight_smile:

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

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 :wink:

···

#----------------------------------------------------
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

thanks to you both, that works a charm :slight_smile:

"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 :wink:

#----------------------------------------------------
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

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 :slight_smile:

"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 :wink:
>
> #----------------------------------------------------
> 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
>
>