views:

3509

answers:

7

I'm writing a Rails application, but can't seem to find how to do relative time, i.e. if given a certain Time class, it can calculate "30 seconds ago" or "2 days ago" or if it's longer than a month "9/1/2008", etc.

+1  A: 

You can use the arithmetic operators to do relative time.

Time.now - 2.days

Will give you 2 days ago.

TonyLa
Did you know about 2.days.ago ?
webmat
+2  A: 

Something like this would work.

def relative_time(start_time)
  diff_secconds = Time.now - start_time
  case diff_seconds
    when 0 .. 59
      puts "#{diff_seconds} seconds ago"
    when 60 .. (3600-1)
      puts "#{diff_seconds/60} minutes ago"
    when 3600 .. (3600*24-1)
      puts "#{diff_seconds/360} hours ago"
    when (3600*24) .. (3600*24*30) 
      puts "#{diff_seconds/(3600*24)} days ago"
    else
      puts start_time.strftime("%m/%d/%Y")
  end
end
Gordon Wilson
This is essentially a reimplementation of the distance_of_time_in_words helper: http://api.rubyonrails.com/classes/ActionView/Helpers/DateHelper.html#M001712
nertzy
yes, and yes ; )
Gordon Wilson
+2  A: 

What about

30.seconds.ago
2.days.ago

Or something else you were shooting for?

Honza
+33  A: 

Sounds like you're looking for the time_ago_in_words method (or distance_of_time_in_words), from ActiveSupport. Call it like this:

<%= time_ago_in_words(timestamp) %>

Check the docs for it here.

Ben Scofield
+9  A: 

I've written this, but have to check the existing methods mentioned to see if they are better.

module PrettyDate
def to_pretty
a = (Time.now-self).to_i

case a
  when 0 then return 'just now'
  when 1 then return 'a second ago'
  when 2..59 then return a.to_s+' seconds ago' 
  when 60..119 then return 'a minute ago' #120 = 2 minutes
  when 120..3540 then return (a/60).to_i.to_s+' minutes ago'
  when 3541..7100 then return 'an hour ago' # 3600 = 1 hour
  when 7101..82800 then return ((a+99)/3600).to_i.to_s+' hours ago' 
  when 82801..172000 then return 'a day ago' # 86400 = 1 day
  when 172001..518400 then return ((a+800)/(60*60*24)).to_i.to_s+' days ago'
  when 518400..1036800 then return 'a week ago'
end
return ((a+180000)/(60*60*24*7)).to_i.to_s+' weeks ago'
end
end

Time.send :include, PrettyDate
MattW.
Hum, I read first ruby, and ruby don't have ActiveSupport out of the box. So I think this post is more ruby.However in the actual question there is a mention of rails.
Jonke
Rails is a web framework and the underlying language is ruby. So it is normal to get some ruby code on a rails question. Even if standard ruby does not include ActiveRecord, it is supported with just a "gem install activerecord" command.
MickTaiwan
A: 

i think of this as fuzzy timestamps, or "web 2.0" intervals. Probably all the major ajax libs/frameworks/plugins can do this, also:

dojo: http://www.oreillynet.com/onlamp/blog/2008/08/dojo_goodness_part_10_its_a_do_1.html

jquery: http://timeago.yarp.com/

Gene T
+1  A: 

<shameless self promotion>There's a plugin for this. Check out the files on GitHub.</shameless self promotion>

James A. Rosen