Name this method...

Discussion in 'Ruby' started by Daniel Waite, Dec 2, 2007.

  1. Daniel Waite

    Daniel Waite Guest

    First off, if there's already a method that does this please point it
    out; I couldn't find one so I wrote my own.

    It's currently called #to_elapsed_time and is attached to Fixnum. What
    it does...

    >> 10.to_elapsed_time

    => {:days=>0, :minutes=>0, :seconds=>10, :hours=>0}
    >> 75.to_elapsed_time

    => {:days=>0, :minutes=>1, :seconds=>15, :hours=>0}
    >> 75018.to_elapsed_time

    => {:days=>0, :minutes=>50, :seconds=>18, :hours=>20}
    >> 789010.to_elapsed_time

    => {:days=>9, :minutes=>10, :seconds=>10, :hours=>3}

    The current name makes sense to me because I wrote it with this in mind:

    started = Time.now
    ended = Time.now + some_time_into_the_future
    elapsed = (ended.to_i - started.to_i).to_elapsed_time

    Looking at it now I suppose I could attach it to Time, too...

    time_1.elapsed(time_2)

    That would be kinda cool, too.

    What do you think?
    --
    Posted via http://www.ruby-forum.com/.
     
    Daniel Waite, Dec 2, 2007
    #1
    1. Advertising

  2. Daniel Waite

    thefed Guest

    On Dec 2, 2007, at 3:58 PM, Daniel Waite wrote:

    > First off, if there's already a method that does this please point it
    > out; I couldn't find one so I wrote my own.
    >
    > It's currently called #to_elapsed_time and is attached to Fixnum. What
    > it does...
    >
    >>> 10.to_elapsed_time

    > => {:days=>0, :minutes=>0, :seconds=>10, :hours=>0}
    >>> 75.to_elapsed_time

    > => {:days=>0, :minutes=>1, :seconds=>15, :hours=>0}
    >>> 75018.to_elapsed_time

    > => {:days=>0, :minutes=>50, :seconds=>18, :hours=>20}
    >>> 789010.to_elapsed_time

    > => {:days=>9, :minutes=>10, :seconds=>10, :hours=>3}


    That's DEFINITELY a nice method to have around :)

    Unfortunately....

    > started = Time.now
    > ended = Time.now + some_time_into_the_future
    > elapsed = (ended.to_i - started.to_i).to_elapsed_time


    puts ended - started
    #=> Some Time

    already works

    Don't trash your method though! It will probably come in handy one day

    Ari Brown
    --------------------------------------------|
    If you're not living on the edge,
    then you're just wasting space.
     
    thefed, Dec 2, 2007
    #2
    1. Advertising

  3. Daniel Waite

    Daniel Waite Guest

    thefed wrote:
    > On Dec 2, 2007, at 3:58 PM, Daniel Waite wrote:
    >
    >>>> 75018.to_elapsed_time

    >> => {:days=>0, :minutes=>50, :seconds=>18, :hours=>20}
    >>>> 789010.to_elapsed_time

    >> => {:days=>9, :minutes=>10, :seconds=>10, :hours=>3}

    >
    > That's DEFINITELY a nice method to have around :)


    Thank you!

    > Unfortunately....
    >
    >> started = Time.now
    >> ended = Time.now + some_time_into_the_future
    >> elapsed = (ended.to_i - started.to_i).to_elapsed_time

    >
    > puts ended - started
    > #=> Some Time
    >
    > already works


    I aware of that, but didn't want a float due to its inaccuracies.
    (Though I admit I'm still uncertain exactly HOW those inconsistencies
    manifest themselves, I know they can be wrong from time to time.) I
    suppose I could write..

    (ended - started).to_i

    > Don't trash your method though! It will probably come in handy one day


    Thank you again! :)

    I've added elapsed to Time, which piggybacks off Fixnum's implementation
    (that sounds bad... is it?)

    class Fixnum

    def seconds_into_time
    elapsed_time = Hash.new
    elapsed_time[:days], remainder = self.divmod(86400)
    elapsed_time[:hours], remainder = remainder.divmod(3600)
    elapsed_time[:minutes], remainder = remainder.divmod(60)
    elapsed_time[:seconds] = remainder
    elapsed_time
    end

    end

    class Time

    def elapsed(time)
    (time - self).to_i.seconds_into_time
    end

    end

    As you can see I renamed it to #seconds_into_time. Any thoughts on that
    name?

    I like the to_xxx family of methods, but...

    100.to_time_breakdown
    100.from_seconds_into_time_breakdown
    100.to_time
    100.to_elapsed_time

    None of them feel right. I'm sad. =(
    --
    Posted via http://www.ruby-forum.com/.
     
    Daniel Waite, Dec 2, 2007
    #3
  4. Daniel Waite

    Chris Shea Guest

    On Dec 2, 1:58 pm, Daniel Waite <> wrote:
    > First off, if there's already a method that does this please point it
    > out; I couldn't find one so I wrote my own.
    >
    > It's currently called #to_elapsed_time and is attached to Fixnum. What
    > it does...
    >
    > >> 10.to_elapsed_time

    >
    > => {:days=>0, :minutes=>0, :seconds=>10, :hours=>0}>> 75.to_elapsed_time
    >
    > => {:days=>0, :minutes=>1, :seconds=>15, :hours=>0}>> 75018.to_elapsed_time
    >
    > => {:days=>0, :minutes=>50, :seconds=>18, :hours=>20}>> 789010.to_elapsed_time
    >
    > => {:days=>9, :minutes=>10, :seconds=>10, :hours=>3}
    >
    > The current name makes sense to me because I wrote it with this in mind:
    >
    > started = Time.now
    > ended = Time.now + some_time_into_the_future
    > elapsed = (ended.to_i - started.to_i).to_elapsed_time
    >
    > Looking at it now I suppose I could attach it to Time, too...
    >
    > time_1.elapsed(time_2)
    >
    > That would be kinda cool, too.
    >
    > What do you think?
    > --
    > Posted viahttp://www.ruby-forum.com/.


    You might want to take a look at the Duration gem: http://rubyforge.org/projects/duration/

    It's very similar to what you have here.

    HTH,
    Chris
     
    Chris Shea, Dec 2, 2007
    #4
  5. Daniel Waite

    Daniel Waite Guest

    Chris Shea wrote:
    > You might want to take a look at the Duration gem:
    > http://rubyforge.org/projects/duration/
    >
    > It's very similar to what you have here.


    Damn it! That makes so much more sense! Just like Ruby makes the concept
    of a range explicit via Range, I should have thought to make _duration_
    (brilliant name, by the way) explicit via Duration.

    Objects, Daniel, objects! Not objects grafted as methods onto other
    objects!

    Here's an excerpt from the doc:

    require 'duration'
    => true
    d = Duration.new(60 * 60 * 24 * 10 + 120 + 30)
    => #<Duration: 1 week, 3 days, 2 minutes and 30 seconds>
    d.to_s
    => "1 week, 3 days, 2 minutes and 30 seconds"
    [d.weeks, d.days]
    => [1, 3]
    d.days = 7; d
    => #<Duration: 2 weeks, 2 minutes and 30 seconds>
    d.strftime('%w w, %d d, %h h, %m m, %s s')
    => "2 w, 0 d, 0 h, 2 m, 30 s"

    And a direct link to the docs:
    http://duration.rubyforge.org/doc/

    Thanks Chris for pointing this out to me.
    --
    Posted via http://www.ruby-forum.com/.
     
    Daniel Waite, Dec 2, 2007
    #5
  6. Daniel Waite

    Phrogz Guest

    On Dec 2, 1:58 pm, Daniel Waite <> wrote:
    > First off, if there's already a method that does this please point it
    > out; I couldn't find one so I wrote my own.
    >
    > It's currently called #to_elapsed_time and is attached to Fixnum. What
    > it does...
    >
    > >> 10.to_elapsed_time

    >
    > => {:days=>0, :minutes=>0, :seconds=>10, :hours=>0}>> 75.to_elapsed_time
    >
    > => {:days=>0, :minutes=>1, :seconds=>15, :hours=>0}>> 75018.to_elapsed_time
    >
    > => {:days=>0, :minutes=>50, :seconds=>18, :hours=>20}>> 789010.to_elapsed_time
    >
    > => {:days=>9, :minutes=>10, :seconds=>10, :hours=>3}
    >
    > The current name makes sense to me because I wrote it with this in mind:
    >
    > started = Time.now
    > ended = Time.now + some_time_into_the_future
    > elapsed = (ended.to_i - started.to_i).to_elapsed_time


    Not as cool as the duration gem, but I offer this also:
    http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/266462
     
    Phrogz, Dec 3, 2007
    #6
  7. Phrogz wrote:
    > On Dec 2, 1:58 pm, Daniel Waite <> wrote:
    >> started = Time.now
    >> ended = Time.now + some_time_into_the_future
    >> elapsed = (ended.to_i - started.to_i).to_elapsed_time

    >
    > Not as cool as the duration gem, but I offer this also:
    > http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/266462


    That approach works for a while but you can't accurately represent
    months or years because some months and some years have more seconds in
    them than some others. Let's see if I can get anyone interested in my
    implementation...


    require "date
    class Time

    #get the difference between 2 times as number of years+months+days+...
    def diff(other)
    t1,t2 = [self,other].map do |t|
    DateTime.new(t.year, t.mon, t.day, t.hour, t.min, t.sec,
    Rational(t.utc_offset, 86400))
    end
    diff = Hash.new(0)
    diff[:past] = t2 < t1
    t1,t2 = t2,t1 if diff[:past]
    t = t1
    diff[:str] = ""
    t = calc_diff(diff,:year, t2){ |n| t >> 12*n }
    t = calc_diff(diff,:month, t2){ |n| t >> n }
    t = calc_diff(diff,:day, t2){ |n| t + n }
    t = calc_diff(diff,:hour, t2){ |n| t + Rational(n,24) }
    t = calc_diff(diff,:minute,t2){ |n| t + Rational(n,24*60) }
    t = calc_diff(diff,:second,t2){ |n| t + Rational(n,24*60*60) }
    diff
    end

    #utility method used above
    def calc_diff(diff,type,t2)
    diff[type] += 1 until t2 < yield(diff[type]+1)
    if diff[type] > 0
    diff[:str] << ", " unless diff[:str].empty?
    diff[:str] << "#{diff[type]} #{type}"
    diff[:str] << "s" if diff[type] > 1
    end
    yield(diff[type])
    end
    private :calc_diff

    #get the difference between 2 times as a human-friendly string
    #e.g. "5 hours, 23 minutes"
    def span_to(other)
    n = other - self
    return "%.3f second" % n if n.abs < 1
    d = self.diff(other)
    str = d[:str].split(",").first(2).join(",")
    str.gsub!(/(\d+)/,'-\1') if d[:past]
    return str
    end

    def time_past
    self.span_to(Time.now)
    end

    def time_left
    Time.now.span_to(self)
    end

    end


    >> t = Time.now

    => Mon Dec 03 13:02:21 JST 2007

    >> t.diff(t+3600)

    => {:hour=>1, :str=>"1 hour", :past=>false}

    >> t.diff(t+86400)

    => {:str=>"1 day", :day=>1, :past=>false}

    >> t.diff(t+123456)

    => {:second=>36, :hour=>10, :str=>"1 day, 10 hours, 17 minutes, 36
    seconds", :day=>1, :past=>false, :minute=>17}

    >> Time.mktime(2007,1,1).diff Time.mktime(2007,10,1)

    => {:str=>"9 months", :past=>false, :month=>9}

    >> Time.mktime(2007,1,1).diff Time.mktime(2008,1,1)

    => {:year=>1, :str=>"1 year", :past=>false}
     
    Daniel DeLorme, Dec 3, 2007
    #7
    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. =?iso-8859-1?B?bW9vcJk=?=
    Replies:
    7
    Views:
    892
    Roedy Green
    Jan 2, 2006
  2. ding feng
    Replies:
    2
    Views:
    2,908
    ding feng
    Jun 25, 2003
  3. Bobby Chamness
    Replies:
    2
    Views:
    2,442
    Joe Smith
    Apr 22, 2007
  4. Jack-2
    Replies:
    3
    Views:
    331
    Jack-2
    Dec 24, 2003
  5. Java  script  Dude

    IE name="name" & form.name property bug

    Java script Dude, Jun 29, 2004, in forum: Javascript
    Replies:
    5
    Views:
    283
    Java script Dude
    Jun 30, 2004
Loading...

Share This Page