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





Вы можете использовать арифметические операторы для определения относительного времени.
Time.now - 2.days
Отдам 2 дня назад.
Знаете ли вы о 2.days.ago?
есть ли метод сокращения для Time.now + 2.days?
@NixNinja: 2.days.since или 2.days.from_now
это назад от того, что задавал вопрос. time_ago_in_words - это ответ на вопрос.
Что-то вроде этого сработает.
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
По сути, это повторная реализация помощника distance_of_time_in_words: api.rubyonrails.com/classes/ActionView/Helpers/…
это означает, что вы не должны его использовать, и вы должны использовать встроенный
Мне это кажется совершенно нормальным. Это позволяет вам настроить остальные струны. то есть «3 секунды назад» или «3 секунды назад»
#{diff_seconds/360} должен быть #{diff_seconds/3600}. Я его отредактировал.
Что о
30.seconds.ago
2.days.ago
Или что-то еще, ради чего вы снимались?
это наоборот от того, о чем говорится в вопросе.
Похоже, вы ищете метод time_ago_in_words (или distance_of_time_in_words) от ActiveSupport. Назовите это так:
<%= time_ago_in_words(timestamp) %>
Подсказки для рубинового новичка, как запустить это в irb? Я запускаю: require 'active_support', а затем пробую 'time_ago_in_words (Time.now)', но функция не найдена.
@cboettig Это не часть ActiveSupport, это определено в ActionView::Helpers::DateHelper.
вам не нужно требовать active_support, если вы используете консоль rails. существует консольный метод helper, который вы можете вызывать и получать доступ к этим методам. helper.time_ago_in_words(timestamp)
Просто fyi, если вы хотите это в irb или обычном Ruby, просто выполните: require 'active_support/core_ext' Сначала, и тогда все готово для использования 7.days.ago и других подобных конструкций.
большой! Я только что пришел сюда, ожидая образец кода, и нашел вот это. Я люблю рубин и рельсы
Конструкция "N.units.since" все еще меня беспокоит, мне жаль, что они не использовали "N.units.hence" для обозначения времени в будущем ...
Вот почему я люблю Руби
Я написал это, но мне нужно проверить существующие методы, упомянутые, чтобы увидеть, лучше ли они.
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
Хм, я прочитал первый рубин, а у рубина нет ActiveSupport из коробки. Так что я думаю, что этот пост более рубиновый. Однако в собственном вопросе есть упоминание о рельсах.
Rails - это веб-фреймворк, а базовый язык - ruby. Так что получить какой-то рубиновый код на вопрос о рельсах - это нормально. Даже если стандартный ruby не включает ActiveRecord, он поддерживается только командой «gem install activerecord».
Вы можете поместить последнюю строку return в операторе case под else и удалить все return.
может кто подскажет почему стоит +99+800+180000?
+99, потому что конец «час назад» заканчивается на 7100, что на 100 секунд меньше двух часов. Аналогично, +800, поскольку 172000 - это 800 секунд меньше двух дней (172800 секунд) и так далее.
хороший пример того, как даже одно значение использования может выиграть от именованной переменной
Взгляните на методы экземпляра здесь:
У этого есть полезные методы, такие как вчера, завтра, начало_недели, назад и т. д.
Примеры:
Time.now.yesterday
Time.now.ago(2.days).end_of_day
Time.now.next_month.beginning_of_month
Я написал гем, который делает это для объектов Rails ActiveRecord. В примере используется created_at, но он также будет работать с updated_at или чем-либо еще с классом ActiveSupport :: TimeWithZone.
Просто установите гем и вызовите «красивый» метод в своем экземпляре TimeWithZone.
Просто чтобы прояснить решение Эндрю Маршалла для использования 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 является объектом Посмотреть в триаде MVC. (Я не согласен, но когда в Риме ...)
Поскольку большинство ответов здесь предлагает 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, а не timeS
Другой подход - выгрузить некоторую логику из бэкэнда и заставить браузер выполнять эту работу, используя плагины Javascript, такие как:
Если вы создаете приложение Rails, вам следует использовать
Time.zone.now
Time.zone.today
Time.zone.yesterday
Это дает вам время или дату в часовом поясе, в котором вы настроили свое приложение Rails.
Например, если вы настроите свое приложение на использование UTC, тогда Time.zone.now всегда будет в формате UTC (например, на него не повлияет изменение британского летнего времени).
Вычислить относительное время легко, например
Time.zone.now - 10.minute
Time.zone.today.days_ago(5)
"вычислить" кажется неправильным словом, вы имели в виду "вывод"?