Ruby / Rails: преобразование даты и времени в естественный язык (например, 23.03.2012 в «эту пятницу») - PullRequest
6 голосов
/ 20 марта 2012

Кто-нибудь знает о геме, методе или фрагменте кода, которые преобразуют значения даты и времени в более удобные для человека ситуации, не создавая ряд правил или не добавляя логику в представление? Например: если сегодня 19.03.2012, конвертируйте:

  • 3/23/2012 до «В эту пятницу»
  • 3/26/2012 до «Следующий понедельник»
  • 3/31/2012 до «Следующие выходные»
  • 4/15/2012 до «Следующий месяц»
  • 3/15/2012 до «Последний четверг»
  • 3/01/2011 до «В прошлом году»

По сути, я ищу противоположность Хроническому самоцвету . Что-то более похожее на distance_of_time_in_words, но с изюминкой. Вместо того, чтобы брать даты из базы данных и отображать их как есть, я хотел бы сделать их более удобными для человека и пригодными для использования при отображении их конечному пользователю.

Ответы [ 3 ]

5 голосов
/ 20 марта 2012

Это маленький взлом, совершенно незаконченный и не элегантный.Но Ruby / Rails так круты с датами, а диапазоны настолько хороши, может быть, если вы не найдете драгоценный камень, что-то вроде этого поможет вам начать:

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
3 голосов
/ 21 июля 2013

Я изменил Ответ Тома , чтобы удовлетворить мои потребности и быть пригодным для использования в качестве отдельного модуля без необходимости включать его в любом месте.Я поместил файл 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)" 
0 голосов
/ 25 марта 2015

Цель драгоценного камня Hublot - решить эту проблему - стать «обратным хроником».

https://github.com/brettshollenberger/hublot

Смежный вопрос: Ruby / Rails - Дата преобразования/ Назад на естественный язык (2011-02-17 => 17 февраля 2011 г.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...