(newb) converting seconds into plain english time units

Discussion in 'Ruby' started by luke, Jul 6, 2005.

  1. luke

    luke Guest

    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
    luke, Jul 6, 2005
    #1
    1. Advertising

  2. luke <> 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
    Robert Klemme, Jul 6, 2005
    #2
    1. Advertising

  3. luke

    daz Guest

    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
    daz, Jul 6, 2005
    #3
  4. luke

    luke Guest

    thanks to you both, that works a charm :)



    "daz" <> wrote in message
    news:...
    >
    > 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, Jul 7, 2005
    #4
  5. luke

    Gene Tani Guest

    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" <> wrote in message
    > news:...
    > >
    > > 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, Jul 7, 2005
    #5
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?UmFlZCBTYXdhbGhh?=

    English/English DLL

    =?Utf-8?B?UmFlZCBTYXdhbGhh?=, Oct 15, 2005, in forum: ASP .Net
    Replies:
    2
    Views:
    1,659
    =?Utf-8?B?UmFlZCBTYXdhbGhh?=
    Oct 16, 2005
  2. IchBin
    Replies:
    1
    Views:
    756
  3. Stu
    Replies:
    7
    Views:
    1,727
    Dave Thompson
    Mar 7, 2005
  4. Michael Tan
    Replies:
    32
    Views:
    929
    Ara.T.Howard
    Jul 21, 2005
  5. Phrogz
    Replies:
    0
    Views:
    142
    Phrogz
    Aug 27, 2007
Loading...

Share This Page