Как вы относитесь к относительному времени в Rails? - PullRequest
222 голосов
/ 12 октября 2008

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

Ответы [ 11 ]

361 голосов
/ 12 октября 2008

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

<%= time_ago_in_words(timestamp) %>
51 голосов
/ 12 октября 2008

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

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
21 голосов
/ 14 сентября 2013

Просто чтобы прояснить решение Эндрю Маршалла об использовании 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 . (Я не согласен, но когда в Риме ...)

20 голосов
/ 12 октября 2008

А как же

30.seconds.ago
2.days.ago

Или что-то еще для чего вы снимали?

12 голосов
/ 12 октября 2008

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

Time.now - 2.days 

даст тебе 2 дня назад.

9 голосов
/ 12 октября 2008

Как-то так будет работать.

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
6 голосов
/ 01 февраля 2014

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

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

<%= time_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 / сообщений / 2012/02/10 / не-потребительные time_ago_in_words /

5 голосов
/ 24 апреля 2013

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

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 голос
/ 22 февраля 2018

Если вы создаете приложение на Rails, вы должны использовать

Time.zone.now
Time.zone.today
Time.zone.yesterday

Это дает вам время или дату в часовом поясе, с которым вы настроили приложение Rails.

Например, если вы сконфигурируете свое приложение для использования UTC, то Time.zone.now всегда будет в UTC времени (например, изменение British Summertime на него не повлияет).

Расчет относительного времени прост, например,

Time.zone.now - 10.minute
Time.zone.today.days_ago(5)
1 голос
/ 16 июля 2013

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

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

https://github.com/brettshollenberger/hublot

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