|
|
# Friendly Timestamp based on:
# http://almosteffortless.com/2007/07/29/the-perfect-timestamp/
# http://railsforum.com/viewtopic.php?pid=33185#p33185
#
# TODO : Update this to support time zones when added to this app, see example links above for possible help with that.
def time_distance_or_time_stamp(time = nil, options = {})
# base time is the time we measure against. It is now by default.
base_time = options[:base_time] ||= Time.now
return '–' if time.nil?
direction = (time.to_i < base_time.to_i) ? "ago" : "from now"
distance_in_minutes = (((base_time - time).abs)/60).round
distance_in_seconds = ((base_time - time).abs).round
case distance_in_minutes
when 0..1 then time = (distance_in_seconds < 60) ? "#{pluralize(distance_in_seconds, 'second')} #{direction}" : "1 minute #{direction}"
when 2..59 then time = "#{distance_in_minutes} minutes #{direction}"
when 60..90 then time = "1 hour #{direction}"
when 90..1440 then time = "#{(distance_in_minutes.to_f / 60.0).round} hours #{direction}"
when 1440..2160 then time = "1 day #{direction}" # 1 day to 1.5 days
when 2160..2880 then time = "#{(distance_in_minutes.to_f / 1440.0).round} days #{direction}" # 1.5 days to 2 days
else time = time.strftime("%a, %d %b %Y")
end
return time_stamp(time) if (options[:show_time] && distance_in_minutes > 2880)
return time
end
def time_stamp(time)
time.to_datetime.strftime("%a, %d %b %Y, %l:%M%P").squeeze(' ')
end
RSPEC TESTS
--
describe "time_ago_or_time_stamp helper method" do
it "should return '–' if time is nil" do
time = nil
time_distance_or_time_stamp(time).should =~ /–/
end
it "should return detailed timestamp if distance > 2880 minutes and options[:show_time] = true" do
base_time = Time.utc(1966,"oct",25,05,35,0)
time = base_time + (2881*60)
time_distance_or_time_stamp(time, {:base_time => base_time, :show_time => true}).should =~ /Thu, 27 Oct 1966, 12:00am/
end
it "should not return detailed timestamp if distance > 2880 minutes and options[:show_time] = false" do
base_time = Time.utc(1966,"oct",25,05,35,0)
time = base_time + (2881*60)
time_distance_or_time_stamp(time, {:base_time => base_time, :show_time => false}).should =~ /Thu, 27 Oct 1966/
end
it "should not return detailed timestamp if distance > 2880 minutes and options[:show_time] is not specified" do
base_time = Time.utc(1966,"oct",25,05,35,0)
time = base_time + (2881*60)
time_distance_or_time_stamp(time, {:base_time => base_time}).should =~ /Thu, 27 Oct 1966/
end
it "should return '1 second ago' when 1 second ago" do
time = 1.second.ago
time_distance_or_time_stamp(time).should =~ /1 second ago/
end
it "should return '1 second from now' when 1 second from now" do
time = 1.second.from_now
time_distance_or_time_stamp(time).should =~ /1 second from now/
end
it "should return '59 second ago' when 59 seconds ago" do
time = 59.seconds.ago
time_distance_or_time_stamp(time).should =~ /59 seconds ago/
end
it "should return '59 second from now' when 59 seconds from now" do
time = 59.seconds.from_now
time_distance_or_time_stamp(time).should =~ /59 seconds from now/
end
it "should return '1 minute ago' when 1 minute ago" do
time = 60.seconds.ago
time_distance_or_time_stamp(time).should =~ /1 minute ago/
end
it "should return '1 minute from now' when 1 minute from now" do
time = 60.seconds.from_now
time_distance_or_time_stamp(time).should =~ /1 minute from now/
end
it "should return '2 minutes ago' when 2 minutes ago" do
time = 2.minutes.ago
time_distance_or_time_stamp(time).should =~ /2 minutes ago/
end
it "should return '2 minutes from now' when 2 minutes from now" do
time = 2.minutes.from_now
time_distance_or_time_stamp(time).should =~ /2 minutes from now/
end
it "should return '59 minutes ago' when 59 minutes ago" do
time = 59.minutes.ago
time_distance_or_time_stamp(time).should =~ /59 minutes ago/
end
it "should return '59 minutes from now' when 59 minutes from now" do
time = 59.minutes.from_now
time_distance_or_time_stamp(time).should =~ /59 minutes from now/
end
it "should return '1 hour ago' when 1 hour ago" do
time = 1.hour.ago
time_distance_or_time_stamp(time).should =~ /1 hour ago/
end
it "should return '1 hour from now' when 1 hour from now" do
time = 1.hour.from_now
time_distance_or_time_stamp(time).should =~ /1 hour from now/
end
it "should return '23 hour ago' when 23 hours ago" do
time = 23.hours.ago
time_distance_or_time_stamp(time).should =~ /23 hours ago/
end
it "should return '23 hour from now' when 23 hours from now" do
time = 23.hours.from_now
time_distance_or_time_stamp(time).should =~ /23 hours from now/
end
it "should return '24 hours ago' when 24 hours ago" do
time = 24.hours.ago
time_distance_or_time_stamp(time).should =~ /24 hours ago/
end
it "should return '24 hours from now' when 24 hours from now" do
time = 24.hours.from_now
time_distance_or_time_stamp(time).should =~ /24 hours from now/
end
it "should return '1 day ago' when 25 hours ago" do
time = 25.hours.ago
time_distance_or_time_stamp(time).should =~ /1 day ago/
end
it "should return '1 day from now' when 25 hours from now" do
time = 25.hours.from_now
time_distance_or_time_stamp(time).should =~ /1 day from now/
end
it "should return '1 day ago' when 36 hours ago" do
time = 36.hours.ago
time_distance_or_time_stamp(time).should =~ /1 day ago/
end
it "should return '1 day from now' when 36 hours from now" do
time = 36.hours.from_now
time_distance_or_time_stamp(time).should =~ /1 day from now/
end
it "should return '2 days ago' when 37 hours ago" do
time = 37.hours.ago
time_distance_or_time_stamp(time).should =~ /2 days ago/
end
it "should return '2 days from now' when 37 hours from now" do
time = 37.hours.from_now
time_distance_or_time_stamp(time).should =~ /2 days from now/
end
it "should return '2 days ago' when 48 hours ago" do
time = 48.hours.ago
time_distance_or_time_stamp(time).should =~ /2 days ago/
end
it "should return '2 days from now' when 48 hours from now" do
time = 48.hours.from_now
time_distance_or_time_stamp(time).should =~ /2 days from now/
end
it "should return time_stamp without 'ago' when 49+ hours ago" do
time = 49.hours.ago
time_distance_or_time_stamp(time).should_not =~ /ago/
end
it "should return time_stamp without 'from now' when 49+ hours from now" do
time = 49.hours.from_now
time_distance_or_time_stamp(time).should_not =~ /from now/
end
it "should return time_stamp with only day & date when 49+ hours ago" do
time = Time.utc(1966,"oct",25,05,35,0)
time_distance_or_time_stamp(time).should =~ /Tue, 25 Oct 1966/
end
it "should return time_stamp with only day & date when 49+ hours from now" do
time = Time.utc(2020,"oct",25,05,35,0)
time_distance_or_time_stamp(time).should =~ /Sun, 25 Oct 2020/
end
end
describe "time_stamp helper method" do
it "should return a properly formatted timestamp" do
time = Time.utc(1966,"oct",25,05,35,0)
time_stamp(time).should =~ /Tue, 25 Oct 1966, 5:35am/
end
end
|