Я пишу приложение на Rails, но, похоже, не могу найти, как сделать относительное время, то есть, если задан определенный класс времени, оно может вычислять «30 секунд назад» или «2 дня назад» или если оно длиннее месяца «01.09.2008» и др.
Я пишу приложение на Rails, но, похоже, не могу найти, как сделать относительное время, то есть, если задан определенный класс времени, оно может вычислять «30 секунд назад» или «2 дня назад» или если оно длиннее месяца «01.09.2008» и др.
Ответы:
Похоже, вы ищете time_ago_in_words
метод (или distance_of_time_in_words
), из ActiveSupport. Назовите это так:
<%= time_ago_in_words(timestamp) %>
ActiveSupport
, это определено в ActionView::Helpers::DateHelper
.
helper
который вы можете вызвать и получить доступ к этим методам. helper.time_ago_in_words(timestamp)
require 'active_support/core_ext'
сначала, а затем все готово для использования 7.days.ago
и других подобных конструкций.
Я написал это, но должен проверить существующие методы, упомянутые, чтобы видеть, лучше ли они.
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
return
строку внутри case
оператора else
и удалить все return
s.
+99
+800
+180000
?
Просто чтобы прояснить решение Эндрю Маршалла об использовании 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, импортированный по умолчанию.
NB Это не "путь рельсов", чтобы импортировать помощников в ваши контроллеры. Помощники для того, чтобы помочь взглядам. Time_ago_in_words метод решил быть вид объект в MVC триаде. (Я не согласен, но когда в Риме ...)
Вы можете использовать арифметические операторы, чтобы сделать относительное время.
Time.now - 2.days
Даст вам 2 дня назад.
2.days.since
или2.days.from_now
Нечто подобное будет работать.
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
#{diff_seconds/360}
должно быть #{diff_seconds/3600}
. Я редактировал это.
Поскольку большинство ответов здесь предлагает 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/posts/2012/02/10/not-use-time_ago_in_words/
time_ago_in_words
не время S
Взгляните на методы экземпляра здесь:
Это имеет полезные методы, такие как вчера, завтра, begin_of_week, назад и т. Д.
Примеры:
Time.now.yesterday
Time.now.ago(2.days).end_of_day
Time.now.next_month.beginning_of_month
Я написал гем, который делает это для объектов Rails ActiveRecord. В этом примере используется create_at, но он также будет работать с updated_at или чем-то еще с классом ActiveSupport :: TimeWithZone.
Просто установите gem и вызовите метод pretty в вашем экземпляре TimeWithZone.
Если вы создаете приложение 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)
Другой подход заключается в том, чтобы выгрузить некоторую логику из серверной части и заставить браузер выполнять эту работу с помощью плагинов Javascript, таких как: