Как вы относитесь к относительному времени в Rails?

225

Я пишу приложение Rails, но, похоже, не могу найти, как сделать относительное время, т.е. если задан определенный класс времени, он может вычислить "30 секунд назад" или "2 дня назад" или если он длиннее чем месяц "9/1/2008" и т.д.

  • 1
    «Рассчитать», кажется, неправильное слово, вы имели в виду «выход»?
Теги:

10 ответов

352

Похоже, вы ищете метод time_ago_in_words (или distance_of_time_in_words), из ActiveSupport. Назовите это так:

<%= time_ago_in_words(timestamp) %>
  • 4
    Советы рубиновому новичку о том, как запустить это в IRB? Я запускаю: требуют 'active_support', а затем попробуйте 'time_ago_in_words (Time.now)', но функция не найдена.
  • 2
    @cboettig Он не является частью ActiveSupport , он определен в ActionView::Helpers::DateHelper .
Показать ещё 5 комментариев
49

Я написал это, но должен проверить существующие методы, чтобы увидеть, лучше ли они.

module PrettyDate
  def to_pretty
    a = (Time.now-self).to_i

    case a
      when 0 then 'just now'
      when 1 then 'a second ago'
      when 2..59 then a.to_s+' seconds ago' 
      when 60..119 then 'a minute ago' #120 = 2 minutes
      when 120..3540 then (a/60).to_i.to_s+' minutes ago'
      when 3541..7100 then 'an hour ago' # 3600 = 1 hour
      when 7101..82800 then ((a+99)/3600).to_i.to_s+' hours ago' 
      when 82801..172000 then 'a day ago' # 86400 = 1 day
      when 172001..518400 then ((a+800)/(60*60*24)).to_i.to_s+' days ago'
      when 518400..1036800 then 'a week ago'
      else ((a+180000)/(60*60*24*7)).to_i.to_s+' weeks ago'
    end
  end
end

Time.send :include, PrettyDate
  • 1
    Хм, я прочитал первый ruby, а у ruby нет ActiveSupport из коробки. Поэтому я думаю, что этот пост более рубиновый. Однако в актуальном вопросе есть упоминание о рельсах.
  • 0
    Rails - это веб-фреймворк, а основным языком является ruby. Так что нормально получить какой-нибудь рубиновый код по рельсам. Даже если стандартный ruby не включает ActiveRecord, он поддерживается только командой «gem install activerecord».
Показать ещё 5 комментариев
19

Просто чтобы прояснить решение Эндрю Маршалла для использования time_ago_in_words
(Для Rails 3.0 и Rails 4.0)

Если вы находитесь в режиме просмотра

<%= time_ago_in_words(Date.today - 1) %>

Если вы находитесь в контроллере

include ActionView::Helpers::DateHelper
def index
  @sexy_date = time_ago_in_words(Date.today - 1)
end

У контроллеров не установлен модуль ActionView:: Helpers:: DateHelper по умолчанию.

N.B. Это не "путь рельсов" для импорта помощников в ваши контроллеры. Помощники предназначены для просмотра взглядов. Метод time_ago_in_words был решен как объект view в триаде MVC. (Я не согласен, но когда в Риме...)

18

Что насчет

30.seconds.ago
2.days.ago

Или что-то еще, за что вы стреляли?

  • 19
    это отстает от того, что ставит вопрос.
12

Вы можете использовать арифметические операторы для выполнения относительного времени.

Time.now - 2.days 

Дает вам 2 дня назад.

  • 10
    Знаете ли вы о 2.days.ago?
  • 2
    есть ли сокращенный метод для `Time.now + 2.days '?
Показать ещё 3 комментария
7

Что-то вроде этого будет работать.

def relative_time(start_time)
  diff_seconds = Time.now - start_time
  case diff_seconds
    when 0 .. 59
      puts "#{diff_seconds} seconds ago"
    when 60 .. (3600-1)
      puts "#{diff_seconds/60} minutes ago"
    when 3600 .. (3600*24-1)
      puts "#{diff_seconds/3600} hours ago"
    when (3600*24) .. (3600*24*30) 
      puts "#{diff_seconds/(3600*24)} days ago"
    else
      puts start_time.strftime("%m/%d/%Y")
  end
end
  • 11
    По сути это повторная реализация помощника distance_of_time_in_words : api.rubyonrails.com/classes/ActionView/Helpers/…
  • 1
    да и да; )
Показать ещё 3 комментария
5

Так как наиболее ответ здесь предлагает time_ago_in_words.

Вместо использования:

<%= times_ago_in_words(comment.created_at) %>

В Rails, Предпочитаете:

<abbr class="timeago" title="<%= comment.created_at.getutc.iso8601 %>">
  <%= comment.created_at.to_s %>
</abbr>

вместе с библиотекой jquery http://timeago.yarp.com/ с кодом:

$("abbr.timeago").timeago();

Основное преимущество: кеширование

http://rails-bestpractices.com/posts/2012/02/10/not-use-time_ago_in_words/

  • 1
    на самом деле это время time_ago_in_words не время S
5

Посмотрите на методы экземпляра здесь:

http://apidock.com/rails/Time

У этого есть полезные методы, такие как вчера, завтра, begin_of_week, назад и т.д.

Примеры:

Time.now.yesterday
Time.now.ago(2.days).end_of_day
Time.now.next_month.beginning_of_month
1

Я написал камень, который делает это для объектов Rails ActiveRecord. В примере используется created_at, но он также будет работать на update_at или что-либо с классом ActiveSupport:: TimeWithZone.

Просто установите gem и вызовите метод "pretty" на вашем экземпляре TimeWithZone.

https://github.com/brettshollenberger/hublot

0

Другой подход заключается в том, чтобы выгрузить некоторую логику из бэкэнда и выполнить его работу с помощью Javascript-плагинов, например:

jQuery время назад или его адаптация Rails Gem

Ещё вопросы

Сообщество Overcoder
Наверх
Меню