计算两个日期之间的天数

183

如何计算这两个日期之间的天数?

start_date = Date.parse "2012-03-02 14:46:21 +0100"
end_date =  Date.parse "2012-04-02 14:46:21 +0200"
12个回答

253
使用 Date(和 DateTime)类,您可以执行 (end_date - start_date).to_i 来获取天数差异。

5
@MichaelDurrant,你做出了一个无根据的假设。该用户并没有指定它们是否为字符串。事实上,由于他们正在使用Rails,最可能的情况是日期来自ActiveRecord,它会自动将其转换为日期对象。给出的文本与日期对象表示完全相同,这极有可能来自本地源。 - Andrew France
100
这让我知道了用Rails v3/4的差异,不是以天为单位而是以秒为单位。 - 2called-chaos
8
据我所知,Ruby和ActiveSupport的所有最新版本,包括2.0和4.1.0,行为都保持不变。但是Time对象确实会返回秒数。 - Andrew France
8
为了扩展@2called-chaos的答案,如果你想得到天数,你需要计算(end_date - start_date)/1.day,这会得到一个浮点数。如果你只想要整天数,你可以使用((end_date - start_date)/1.day).ceil。 - David K.
4
除了@2called-chaos的评论错误地提到了“Time”对象而不是“Date”对象之外,其余部分都正确。也许你可以更新你的评论中的命名以反映它们不是日期? - Andrew France
显示剩余4条评论

144
假设在Rails中,假设 end_datestart_date 都属于 ActiveSupport::TimeWithZone 类,那么你可以使用以下方法:
(end_date.to_date - start_date.to_date).to_i

3
如果涉及到表格字段,这个回答是正确的选择;而不是这里评分最高的回答。 - Ben
1
对于(Time.zone.now.to_date - 23.hours.ago.to_date).to_i无效,它给出1,应该是0。 - Yuri Ghensev
4
@YuriGhensev,这取决于您运行示例代码的时间,例如现在Time.zone.now.to_date返回“Wed, 15 Nov 2017”,而23.hours.ago.to_date返回“Tue, 14 Nov 2017”。除非您在午夜前一小时运行代码,否则天数差异应该是1,而且应该是1。 - lee

40
Rails内置了一些帮助程序,可能可以解决你的问题。需要记住的一件事是它们属于Actionview Helpers的一部分,因此不能直接从控制台访问。
尝试这个。
<% start_time =  "2012-03-02 14:46:21 +0100" %>
<% end_time   =  "2012-04-02 14:46:21 +0200" %>
<%= distance_of_time_in_words(start_time, end_time)  %>

 "about 1 month"

1
@MaayanNaveh 当你需要进行实际计算时,这个数字不应该被忽略。 - Fedcomp
这个问题是其中一种情况,即问题本身最好用不同的方式提问。如果你按照其他答案操作,有时你需要显示几周或几年,而不是天数。这真的应该被接受为“正确”的Rails答案。 - Dylan Pierce

36

获取时间范围内的天数(即所有天数的计数)

(start_date..end_date).count
(start_date..end_date).to_a.size
#=> 32

获取2个日期之间的天数

(start_date...end_date).count
(start_date...end_date).to_a.size
#=> 31

感谢@a14m!给了我一种包含和排除日期捕获的方法 :) - Kris Boyd

35

我总能在几秒钟内得到结果,所以这对我有用:

(Time.now - self.created_at) / 86400

1
@Epigene,“1.day”并不是OP请求的“ruby”(在标签中)。它是“Rails”或更具体地说是“active support”,尽管“created_at”基本上是Rails中的一个“Model”方法,所以... - Roko

20

截至目前,之前的所有回答都没有正确地给出两个日期之间的天数差。

最接近正确答案的是来自thatdankent 的回答。完整的答案会先将日期转换为to_i 然后进行除法计算:

(Time.now.to_i - 23.hours.ago.to_i) / 86400
>> 0

(Time.now.to_i - 25.hours.ago.to_i) / 86400
>> 1

(Time.now.to_i - 1.day.ago.to_i) / 86400
>> 1
在问题的具体示例中,如果经过的时间是相关的,就不应该解析为Date。而应该使用Time.parse

当时间跨越夏令时转换时,这可能不会按预期工作。在这种情况下,夏令时过渡日的长度合法地少于24小时,但由于整数算术,那一天将根本不会反映出来。 - PinnyM

9

虽然有些晚了,但这可能会对其他人有所帮助:

end_date.mjd - start_date.mjd

https://apidock.com/ruby/Date/mjd

提示:这只适用于日期对象,不适用于时间对象。


6
要计算两个日期之间的整天数(DateTime对象):
((end_at - start_at).to_f / 1.day).floor

与Yuri所提供的答案相同,存在夏令时问题。时间计算从来不像你期望的那样直接简单 :) - PinnyM

4
目前我见过的最好的解决方案是采用以下模式:
(end_date.beginning_of_day - Time.now.utc.beginning_of_day).seconds.in_days

2
获取两个日期之间的天数差异:
(start.to_date...end.to_date).count - 1
or 
(end.to_date - start.to_date).to_i

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接