Ruby / Rails: Convert date and time to natural language (e.g. 3/23/2012 - “this Friday”)

Does anyone know about a gem, method or piece of code that converts datetime values ​​to more convenient for a person without creating a series of rules or putting a bunch of logic in a view? For example: if today is 3/19/2012, convert:

  • 3/23/2012 - "This Friday"
  • 3/26/2012 - "Next Monday"
  • 3/31/2012 - "Next Weekend"
  • 4/15/2012 - "Next Month"
  • 3/15/2012 - "Last Thursday"
  • 1/3/2011 for "Last Year"

Basically, I am looking for the opposite of Chronic Stone . Something more like distance_of_time_in_words , but with a twist. Instead of taking dates from the database and displaying them as is, Id like to make them more human-friendly and relative when they are displayed to the end user.

+6
source share
3 answers

This is a small hack, completely unfinished and inelegant. But Ruby / Rails is so amazing with dates, and ranges are so perfect, maybe if you don't find a 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 
+5
source

I changed the Toms response to suit my needs and can be used as a standalone module without turning it on anywhere. I placed the human_date.rb file inside my lib directory. I also fixed a difficult problem with calculating days_difference .

 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 

Using:

 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)" 
+3
source

The goal of the Hublot gem is to solve this problem - to be "reverse chronic."

https://github.com/brettshollenberger/hublot

Related question: Ruby / Rails - convert date / time to natural language (2011-02-17 => February 17, 2011)

0
source

Source: https://habr.com/ru/post/911152/


All Articles