[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Name this method...

Daniel Waite

12/2/2007 8:58:00 PM

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?
--
Posted via http://www.ruby-....

6 Answers

fedzor

12/2/2007 9:18:00 PM

0


On Dec 2, 2007, at 3:58 PM, Daniel Waite wrote:

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

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.



Daniel Waite

12/2/2007 9:26:00 PM

0

thefed wrote:
> On Dec 2, 2007, at 3:58 PM, Daniel Waite 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 :-)

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

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. =(
--
Posted via http://www.ruby-....

Chris Shea

12/2/2007 9:26:00 PM

0

On Dec 2, 1:58 pm, Daniel Waite <rabbitb...@gmail.com> wrote:
> 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?
> --
> Posted viahttp://www.ruby-....

You might want to take a look at the Duration gem: http://rubyforge.org/projects...

It's very similar to what you have here.

HTH,
Chris

Daniel Waite

12/2/2007 9:41:00 PM

0

Chris Shea wrote:
> You might want to take a look at the Duration gem:
> http://rubyforge.org/projects...
>
> 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.rubyforg...

Thanks Chris for pointing this out to me.
--
Posted via http://www.ruby-....

Phrogz

12/3/2007 3:46:00 AM

0

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

Not as cool as the duration gem, but I offer this also:
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-t...

Daniel DeLorme

12/3/2007 4:09:00 AM

0

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:
> http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-t...

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}