【发布时间】:2008-10-12 17:29:56
【问题描述】:
我正在编写一个 Rails 应用程序,但似乎找不到如何计算相对时间,即如果给定某个 Time 类,它可以计算“30 秒前”或“2 天前”或者更长超过一个月“2008 年 9 月 1 日”等。
【问题讨论】:
-
'calculate' 似乎是错误的词,你的意思是'output'吗?
标签: ruby-on-rails ruby
我正在编写一个 Rails 应用程序,但似乎找不到如何计算相对时间,即如果给定某个 Time 类,它可以计算“30 秒前”或“2 天前”或者更长超过一个月“2008 年 9 月 1 日”等。
【问题讨论】:
标签: ruby-on-rails ruby
听起来您正在寻找来自 ActiveSupport 的 time_ago_in_words 方法(或 distance_of_time_in_words)。像这样称呼它:
<%= 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
【讨论】:
case语句中的最后一个return-line放在else下,并删除所有returns。
+99+800+180000吗?
只是为了澄清 Andrew Marshall 使用 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。
注意将助手导入控制器不是“轨道方式”。助手用于帮助视图。 time_ago_in_words 方法被确定为 MVC 三元组中的 view 实体。 (我不同意,但在罗马时......)
【讨论】:
怎么样
30.seconds.ago
2.days.ago
或者你正在拍摄的其他东西?
【讨论】:
您可以使用算术运算符来计算相对时间。
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、ago 等。
例子:
Time.now.yesterday
Time.now.ago(2.days).end_of_day
Time.now.next_month.beginning_of_month
【讨论】:
如果你正在构建一个 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)
【讨论】:
我为 Rails ActiveRecord 对象编写了一个 gem。该示例使用 created_at,但它也适用于 updated_at 或具有 ActiveSupport::TimeWithZone 类的任何内容。
只需 gem install 并在您的 TimeWithZone 实例上调用“漂亮”方法。
【讨论】:
另一种方法是从后端卸载一些逻辑并让浏览器通过使用 Javascript 插件来完成这项工作,例如:
【讨论】: