Ruby / Rails:将日期时间转换为自然语言(例如3/23/2012到“本周五”)

有没有人知道一个gem,方法或代码片段,它会将日期时间值转换为更加人性化的,而不必创建一系列规则或在视图中放入一堆逻辑? 例如:如果今天是2012年3月19日,转换:

  • 2012年3月23日至“本周五”
  • 3/26/2012至“下周一”
  • 2012年3月31日至“下周末”
  • 2012年4月15日至“下个月”
  • 3/15/2012至“上周四”
  • 2011年3月1日至“去年”

基本上,我正在寻找与慢性gem相反的东西。 更类似于distance_of_time_in_words ,但有一点扭曲。 我不想从数据库中取出日期并按原样显示它们,而是在向最终用户显示时,使它们更加人性化并且具有相关性。

这是一个小小的黑客,完全未完成和不优雅。 但是Ruby / Rails在日期方面非常棒,范围非常完美,如果你没有找到gem,这样的东西会让你开始:

 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 

我修改了Tom的答案以满足我的需求,可以作为独立模块使用,而无需将其包含在任何地方。 我将文件human_date.rb放在我的lib目录中。 我还修复了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 

用法:

 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)" 

Hublotgem的目标是解决这个问题 – 成为“逆转慢性”。

https://github.com/brettshollenberger/hublot

相关问题: Ruby / Rails – 将日期/时间转换回自然语言(2011-02-17 => 2011年2月17日)