Name this method

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/\.

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

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.

···

On Dec 2, 2007, at 3:58 PM, Daniel Waite 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.

HTH,
Chris

···

On Dec 2, 1:58 pm, Daniel Waite <rabbitb...@gmail.com> 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/.

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

···

On Dec 2, 1:58 pm, Daniel Waite <rabbitb...@gmail.com> 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

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

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

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. =(

···

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

--
Posted via http://www.ruby-forum.com/\.

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/\.

Phrogz 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}

···

On Dec 2, 1:58 pm, Daniel Waite <rabbitb...@gmail.com> wrote: