为什么Ruby认为公元100年有366天?

时间:2014-04-19 22:42:49

标签: ruby date datetime leap-year

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

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

与DateTime相同。

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

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

是什么给出的?我应该提交错误报告吗?

更新

另外,公元1582年的时间短10天!

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

2 个答案:

答案 0 :(得分:8)

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

答案 1 :(得分:4)

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

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

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

多么令人困惑!

修改

除了关于“合理默认值”的争论之外,与其他语言相比,Ruby似乎对这些日历选择的棘手问题非常灵活。我已经了解到Date和DateTime构造函数可以接收一个“改革日期”常量,它决定了从Julian到Gregorian日历的转换何时发生。默认为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)返回true。为了避免意外,最好使用leap?的方法版本,它使用你选择的任何一个改革日期。

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

Date.new(100, 1, 1, Date::GREGORIAN).leap?
  => false