Name this method...

D

Daniel Waite

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...
=> {: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?
 
T

thefed

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

=> {:days=>9, :minutes=>10, :seconds=>10, :hours=>3}

That's DEFINITELY a nice method to have around :)

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.
 
D

Daniel Waite

thefed said:
That's DEFINITELY a nice method to have around :)

Thank you!
Unfortunately....


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

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

Chris Shea

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


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

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
 
D

Daniel Waite

Chris said:
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.
 
P

Phrogz

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


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

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
 
D

Daniel DeLorme

Phrogz said:
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

=> Mon Dec 03 13:02:21 JST 2007
=> {:hour=>1, :str=>"1 hour", :past=>false}
=> {:str=>"1 day", :day=>1, :past=>false}
=> {:second=>36, :hour=>10, :str=>"1 day, 10 hours, 17 minutes, 36
seconds", :day=>1, :past=>false, :minute=>17}
=> {:str=>"9 months", :past=>false, :month=>9}
=> {:year=>1, :str=>"1 year", :past=>false}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top