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?

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

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 B.
--------------------------------------------|
If you’re not living on the edge,
then you’re just wasting space.

thefed wrote:

On Dec 2, 2007, at 3:58 PM, Daniel W. 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, 1:58 pm, Daniel W. [email protected] wrote:

=> {:days=>0, :minutes=>1, :seconds=>15, :hours=>0}>> 75018.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 S. 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.

On Dec 2, 1:58 pm, Daniel W. [email protected] wrote:

=> {: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 wrote:

On Dec 2, 1:58 pm, Daniel W. [email protected] 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 >> 12n }
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,246060) }
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}