如何找到Ruby中两个Date对象之间的天数?


141

如何找到两个Date对象之间的天数?

Answers:


170

从结束日期减去开始日期:

endDate - beginDate 

2
认为您的意思是从结束日期中减去开始日期:)
Nader

99
那种防蚁eh?

18
注意:如果在irb中使用Wirble(以使输出着色),则有理数末尾将带有1。y!您可能需要使用to_i将结果转换为整数
jwal 2012年

9
如果有DateTime对象,请确保先转换为对象,Date否则它返回秒数(我想)。
约书亚·穆海姆

44
还要注意减去两个Date对象会为您提供一个Rational您可能需要将其类型转换为整数的方法,例如(endDate - beginDate).to_i
MusikAnimal 2015年

98
irb(main):005:0> a = Date.parse("12/1/2010")
=> #<Date: 4911063/2,0,2299161>

irb(main):007:0> b = Date.parse("12/21/2010")
=> #<Date: 4911103/2,0,2299161>

irb(main):016:0> c = b.mjd - a.mjd
=> 20

这使用修改后的儒略日编号

来自维基百科

朱利安日期(JD)是自公元前4713年1月1日格林威治中午(朱利安多产的日历)以来的时间间隔(以天为单位)。


53

这在Ruby 2.0中可能已更改

当我这样做时,我得到了分数。例如在控制台上(irb或rails c)

2.0.0-p195 :005 > require 'date'
 => true 
2.0.0-p195 :006 >  a_date = Date.parse("25/12/2013")
 => #<Date: 2013-12-25 ((2456652j,0s,0n),+0s,2299161j)> 
2.0.0-p195 :007 >  b_date = Date.parse("10/12/2013")
 => #<Date: 2013-12-10 ((2456637j,0s,0n),+0s,2299161j)> 
2.0.0-p195 :008 > a_date-b_date
 => (15/1) 

当然,强制转换为int可以达到预期的结果

2.0.0-p195 :009 > (a_date-b_date).to_i
 => 15 

这也适用于DateTime对象,但是您必须考虑秒数,例如本示例

2.0.0-p195 :017 >   a_date_time = DateTime.now
 => #<DateTime: 2013-12-31T12:23:03-08:00 ((2456658j,73383s,725757000n),-28800s,2299161j)> 
2.0.0-p195 :018 > b_date_time = DateTime.now-20
 => #<DateTime: 2013-12-11T12:23:06-08:00 ((2456638j,73386s,69998000n),-28800s,2299161j)> 
2.0.0-p195 :019 > a_date_time - b_date_time
 => (1727997655759/86400000000) 
2.0.0-p195 :020 > (a_date_time - b_date_time).to_i
 => 19 
2.0.0-p195 :021 > c_date_time = a_date_time-20
 => #<DateTime: 2013-12-11T12:23:03-08:00 ((2456638j,73383s,725757000n),-28800s,2299161j)> 
2.0.0-p195 :022 > a_date_time - c_date_time
 => (20/1) 
2.0.0-p195 :023 > (a_date_time - c_date_time).to_i
 => 20 

29

在Ruby 2.1.3中,情况发生了变化:

> endDate = Date.new(2014, 1, 2)
 => #<Date: 2014-01-02 ((2456660j,0s,0n),+0s,2299161j)> 
> beginDate = Date.new(2014, 1, 1)
 => #<Date: 2014-01-01 ((2456659j,0s,0n),+0s,2299161j)> 
> days = endDate - beginDate
 => (1/1) 
> days.class
 => Rational 
> days.to_i
 => 1 

21

这个怎么样?

(beginDate...endDate).count

范围是一组唯一的序列号。并且...是Range的专有文字。

所以beginDate..(endDate - 1)是一样的。除了不是。

如果beginDate等于endDate,则第一个元素将由于唯一性而被排除,...并将排除最后一个。因此,如果我们想要.count今天和今天之间的日期,它将返回0。


这是一个很好的答案,如果beginDate早于endDate,则它将返回0,这在某些情况下效果很好。另外,如果两个日期相同,则将返回0。它还将返回一个纯整数。其他答案必须转换为整数,或者如果结果为负,则可能必须转换为0。
EmmanuelB



6

所有这些都使我获得了正确的结果,但是我最后还是做了

DateTime.now.mjd - DateTime.parse("01-01-1995").mjd

要指出的一个提示是:Ruby中的DateTime.parse期望将日期指定为DD / MM / YYYY或DD-MM-YYYY。作为美国人,它总是让我失望!
rickumali 2014年

15
@rickumali作为世界其他地区的成员,我感谢Ruby使用“我们的”默认日期格式。
克劳迪奥·霍兰达

7
@rickumali Ruby也接受YYYY-MM-DD格式的日期,这也是每个人都应该使用的格式。
user513951

1

天=(结束日期-开始日期)/(60 * 60 * 24)


5
日期以天为单位,因此您不需要这样做。我认为您的解决方案与DateTime差异相关。
suga_shane 2015年

1

好吧,也要注意“在...之间”的意思。

days_apart = (to - from).to_i     # from + days_apart = to
total_days = (to - from).to_i + 1 # number of "selected" days
in_between_days = (to - from).to_i - 1 # how many days are in between from and to, i.e. excluding those two days
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.