1

以下表达式在 Ruby 中返回 '366',暗示公元 100 年是闰年(它不是闰年):

(Date.ordinal(101) - Date.ordinal(100)).to_i

与日期时间相同。

但是,Date.leap?(100)正确返回false.

版本 1.9.1 的结果相同。和 2.0.0。

是什么赋予了?我应该提交错误报告吗?

更新

此外,显然公元 1582 年还差 10 天!

(Date.ordinal(1583) - Date.ordinal(1582)).to_i
 => 355
4

2 回答 2

8

根据维基百科,100年确实是闰年,1582 年确实跳过了 10 天。

于 2014-04-19T22:55:58.547 回答
4

显然,在 1582-10-15 之前,Ruby 将日期解释为儒略历日期,而不是公历日期。更多细节在这里:

http://teleologi.blogspot.com/2013/05/ruby-times-dates-good-bad-and-so-on.html

显然不是错误,但绝对违反了最小惊喜原则(至少在这个编码员的眼中)。

多么混乱!

编辑

撇开关于“合理的默认值”的争论不谈,与其他语言相比,Ruby 在这些敏感的日历选择问题上似乎相当灵活。我了解到 Date 和 DateTime 构造函数可以接收一个“改革日期”常量,它决定了从儒略历到公历的转换发生的时间。默认值为 ITALY (1582-10-15),但 ENGLAND 也是一个选项(跳转发生在 1752-09-14)。

为了避免在日历之间转换时出现意外,我应该对所有日期都使用公历:

(Date.ordinal(i+1,1,Date::GREGORIAN) - Date.ordinal(i,1,Date::GREGORIAN)).to_i
 => 365

此外,Date.leap?(100)返回“false”,因为它是Date.gregorian_leap?. 同时,Date.julian_leap(100)返回真。为避免意外,最好使用leap? 的方法版本,它使用您选择的任何改革日期。

Date.new(100, 1, 1, Date::JULIAN).leap?
  => true

Date.new(100, 1, 1, Date::GREGORIAN).leap?
  => false
于 2014-04-19T23:01:55.973 回答