Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate a human readable time range using ruby on rails

I'm trying to find the best way to generate the following output

<name> job took 30 seconds <name> job took 1 minute and 20 seconds <name> job took 30 minutes and 1 second <name> job took 3 hours and 2 minutes 

I started this code

def time_range_details   time = (self.created_at..self.updated_at).count   sync_time = case time      when 0..60 then "#{time} secs"            else "#{time/60} minunte(s) and #{time-min*60} seconds"   end end 

Is there a more efficient way of doing this. It seems like a lot of redundant code for something super simple.

Another use for this is:

<title> was posted 20 seconds ago <title> was posted 2 hours ago 

The code for this is similar, but instead i use Time.now:

def time_since_posted   time = (self.created_at..Time.now).count   ...   ... end 
like image 304
csanz Avatar asked Nov 09 '10 16:11

csanz


2 Answers

If you need something more "precise" than distance_of_time_in_words, you can write something along these lines:

def humanize(secs)   [[60, :seconds], [60, :minutes], [24, :hours], [Float::INFINITY, :days]].map{ |count, name|     if secs > 0       secs, n = secs.divmod(count)        "#{n.to_i} #{name}" unless n.to_i==0     end   }.compact.reverse.join(' ') end  p humanize 1234 #=>"20 minutes 34 seconds" p humanize 12345 #=>"3 hours 25 minutes 45 seconds" p humanize 123456 #=>"1 days 10 hours 17 minutes 36 seconds" p humanize(Time.now - Time.local(2010,11,5)) #=>"4 days 18 hours 24 minutes 7 seconds" 

Oh, one remark on your code:

(self.created_at..self.updated_at).count 

is really bad way to get the difference. Use simply:

self.updated_at - self.created_at 
like image 62
Mladen Jablanović Avatar answered Sep 22 '22 13:09

Mladen Jablanović


There are two methods in DateHelper that might give you what you want:

  1. time_ago_in_words

    time_ago_in_words( 1234.seconds.from_now ) #=> "21 minutes"  time_ago_in_words( 12345.seconds.ago )     #=> "about 3 hours" 
  2. distance_of_time_in_words

    distance_of_time_in_words( Time.now, 1234.seconds.from_now ) #=> "21 minutes"  distance_of_time_in_words( Time.now, 12345.seconds.ago )     #=> "about 3 hours" 
like image 24
Doug R Avatar answered Sep 23 '22 13:09

Doug R