Representing a span of time

Say I have two time objects represented as floats like so:

x = 64299600.0
y = 1157489583.2798

I want to subtract x from y and then represent the difference as years,
months, days, hours, minutes and seconds.

I don’t see how the Time library would do this. Has anyone done
something like this? If so, how?

Thanks,
Brad

On Wed, 6 Sep 2006, Brad T. wrote:

Thanks,
Brad

harp:~ > cat a.rb
class Time
module Units
def less() “/” end
def more() “" end
def microseconds() self.send(Float(more,(10 ** -6))) end
def milliseconds() self.send(Float(more,(10 ** -3))) end
def seconds() self end
def minutes() seconds.send(more,60) end
def hours() minutes.send(more,60) end
def days() hours.send(more,24) end
def weeks() days.send(more,7) end
def months() weeks.send(more,4) end
def years() months.send(more,12) end
def decades() years.send(more,10) end
def centuries() decades.send(more,10) end
instance_methods.select{|m| m !~ /__/}.each do |plural|
singular = plural.chop
alias_method singular, plural
end
end
module DiffUnits
include ::Time::Units
def less() "
” end
def more() “/” end
end
alias_method “delta”, “-” unless respond_to? “delta
def - other
ret = delta other
ret.extend DiffUnits
ret
end
end
class Numeric
include ::Time::Units
end

if $0 == FILE
require “yaml”
require “time”

now = Time::now

a = now
y ‘a’ => a

b = now + 2.hours + 2.minutes
y ‘b’ => b

d = b - a
%w( seconds minutes hours days ).each do |unit|
y “d.#{ unit }” => d.send(unit)
end
end

harp:~ > ruby a.rb
a: 2006-09-05 15:26:06.341147 -06:00
b: 2006-09-05 17:28:06.341147 -06:00
d.seconds: 7320.0
d.minutes: 122.0
d.hours: 2.03333333333333
d.days: 0.0847222222222222

regards.

-a

On Tue, 05 Sep 2006 15:26:41 -0600, ara.t.howard wrote:

I don’t see how the Time library would do this. Has anyone done
something like this? If so, how?

[SNIP-CODE]

harp:~ > ruby a.rb
a: 2006-09-05 15:26:06.341147 -06:00
b: 2006-09-05 17:28:06.341147 -06:00
d.seconds: 7320.0
d.minutes: 122.0
d.hours: 2.03333333333333
d.days: 0.0847222222222222

I think he wants something more like this, where all of the different
options collectively add up to the total time interval (rather than
yours
where each different unit of time nonetheless represents the whole span)

class TimeSpan

takes input in seconds because that’s what Time#to_i returns

def initialize(seconds)
@raw_seconds=seconds
breakdown
end

attr_reader :seconds,:minutes,:hours,:days
attr_reader :raw_seconds

private
attr_writer :seconds,:minutes,:hours,:days

[:x=,y] represents that y is the maximum number of x before

carrying over to the next larger unit of time

FACTORS=[[:seconds=,60],[:minutes=,60],
[:hours=,24],[:days=,nil]]

def breakdown
higherintervals=@raw_seconds
FACTORS.each do |method, max|
higherintervals, thisinterval=
higherintervals.divmod(max) unless max==nil
thisinterval=higherintervals if max==nil
send(method,thisinterval)
end
end
end

irb(main):020:0> a=Time.now.to_i
=> 1157512271
irb(main):021:0> b=Time.now.to_i
=> 1157512296
irb(main):025:0> TimeSpan.new(b-a)
=> #<TimeSpan:0xa7cbfc58 @days=0, @hours=0, @minutes=0,
@seconds=25, @raw_seconds=25>

Can’t do years and months without more complicated math, and a definite
knowledge of what the start date and end date are. But at least this
should be closer.

–Ken B.

Brad T. wrote:

Say I have two time objects represented as floats like so:

x = 64299600.0
y = 1157489583.2798

I want to subtract x from y and then represent the difference as years,
months, days, hours, minutes and seconds.

I don’t see how the Time library would do this. Has anyone done
something like this? If so, how?

This may not be exactly what you had in mind, but it’s better than the
other
proposed “solutions” when it comes to displaying the number of months or
years
between two dates: (uses rails activesupport)

class Time
def time_span(other = nil)
other ||= self.utc? ? Time.now.utc : Time.now
other.time_spent(self)
end
def time_spent(other = nil)
other ||= self.utc? ? Time.now.utc : Time.now
n = other - self
case n.abs
when 0…60 #1.minute
“%d seconds” % n
when 0…3600 #1.hour
“%.1f minutes” % (n / 60)
when 0…86400 #1.day
“%.1f hours” % (n / 3600)
else
sign = “-” if self > other
t1,t2 = [other,self].sort
if t2.year != t1.year and t2 >= t1.advance(:years=>1)
nb_years = t2.year - t1.year
t = t1.advance(:years => nb_years)
t = t1.advance(:years => (nb_years -= 1)) if t > t2
“#{sign}%.1f years” % (nb_years + (t2 - t).to_f /
(t.advance(:years=>1)

  • t))
    elsif t2 >= t1.advance(:months=>1)
    nb_months = (t1.year==t2.year ? 0 : 12) + t2.month - t1.month
    t = t1.advance(:months => nb_months)
    t = t1.advance(:months => (nb_months -= 1)) if t > t2
    “#{sign}%.1f months” % (nb_months + (t2 - t).to_f /
    (t.advance(:months=>1) - t))
    else
    “%.1f days” % (n / 1.0.day)
    end
    end
    end
    end

t.time_span(t - 26.seconds)
=> “26 seconds”

t.time_span(t - 26.hours)
=> “1.1 days”

t.time_span(t - 26.days)
=> “26.0 days”

t.time_span(t - 26.months)
=> “2.1 years”