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: