Is anyone aware of a gem, method, or code snippet that will convert datetime values into sometime more human-friendly without having to create a series of rules or put a bunch of logic in the view? For example: if today is 3/19/2012, convert:
Basically, I’m looking for the opposite of the Chronic gem. Something more similar to the distance_of_time_in_words
, but with a twist. Instead of taking dates from the database and displaying them as-is, I’d like to make them more human-friendly and relatable when displayed to the end user.
This is a little hack, totally unfinished and inelegant. But Ruby/Rails is so awesome with dates, and ranges are so perfect, maybe if you don't find the gem, something like this will get you started:
module HumanDate
def date_difference_for_people (from, to)
seconds_in_day = 24 * 60 * 60
days_difference = ((to - from)/seconds_in_day).round
case days_difference
when -1
"yesterday"
when 0
"today"
when 1
"tomorrow"
when 2..days_left_in_week
"this #{day_name(difference)}"
when (days_left_in_week + 1)..(days_left_in_week + 7)
"next week"
when (days_left_in_week + 8)..days_left_in_month
"later this month"
else
"later -- how much left to you :-)"
end
end
def day_name(days_from_now)
days_from_now.days_from_now.strftime("%A")
end
def days_left_in_month
Time.now.end_of_month.day - Time.now.day
end
def days_left_in_week
Time.now.end_of_week.day - Time.now.day
end
end
I modified Tom’s answer to suit my needs and be usable as a standalone module without having to include it anywhere. I placed the file human_date.rb
inside my lib
directory. I also fixed a tricky issue with the days_difference
calculation.
module HumanDate
include ActionView::Helpers::DateHelper
extend self
def date_distance(from, to, long_form = true)
seconds_in_day = 60 * 60 * 24
days_difference = ((to.beginning_of_day.to_datetime - from.beginning_of_day.to_datetime)).floor
case days_difference
when -2
"day before yesterday"
when -1
"yesterday"
when 0
"today"
when 1
"tomorrow"
when 2..6
"this #{day_name(days_difference)}"
when 7..13
"next #{to.strftime("%a")} (#{short_date(days_difference)})"
else
if days_difference > 0
"in #{distance_of_time_in_words(from, to)} (#{short_date(days_difference, long_form)})"
else
"#{distance_of_time_in_words(from, to)} ago (#{short_date(days_difference, long_form)})"
end
end
end
def short_date(this_many, include_day=false)
format_string = "%-b %-d"
format_string = "%a, #{format_string}" if include_day
this_many.days.from_now.strftime(format_string)
end
def day_name(this_many)
this_many.days.from_now.strftime("%A")
end
def days_left_in_month
Time.now.end_of_month.day - Time.now.day
end
def days_left_in_week
Time.now.end_of_week.day - Time.now.day
end
end
Usage:
1.9.3-p392 :001 > HumanDate. date_distance(Time.now, 2.day.ago)
=> "day before yesterday"
1.9.3-p392 :002 > HumanDate. date_distance(Time.now, 3.days.from_now)
=> "this Tuesday"
1.9.3-p392 :003 > HumanDate. date_distance(Time.now, 12.days.from_now)
=> "next Thursday (Aug 1)"
1.9.3-p392 :004 > HumanDate. date_distance(Time.now, 122.days.from_now)
=> "in 4 months (Tue, Nov 19)"
1.9.3-p392 :005 > HumanDate. date_distance(Time.now, 122.days.ago)
=> "4 months ago (Wed, Mar 20)"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With