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

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}

```