1582 年有 10 天从未存在过

Dates That Don't Exist (2015)

1582 年有 10 天从未存在过

1582 年,为了修正历法误差,天主教世界从 Julian Calendar 切换到 Gregorian Calendar,直接抹去了 10 月 5 日至 14 日这 10 天。这意味着在今天的公历体系中,这些日期从未发生过。我测试了 Ruby、Python 和 Perl 三种编程语言对这一历史事实的处理:Ruby 能正确拒绝创建这些不存在的日期,而 Python 和 Perl 却允许生成这些“幽灵日期”。这不仅是历史趣闻,更揭示了现代编程在日期时间实现上对“正确性”的忽视。

本质上,1582 年的那 10 天从未发生,在如今西方几乎通用的 Gregorian Calendar 系统中,它们根本不存在。
  1. jaculabilis

    东正教甚至在那之后很久才改用格里高利历,直到 1929 年才切换。

    严格来说,他们改用是“修订儒略历”[0],而不是格里高利历。此外,东正教内部只有一部分教会进行了切换;其他教会至今仍在沿用儒略历,而且所有教会至今计算复活节(Pascha)日期时仍使用儒略历。

    [0] https://en.wikipedia.org/wiki/Revised_Julian_calendar

  2. pibaker

    这篇文章有点老了。如果晚半年写,本应提到历法技术的一个新进展。

    > 公元 1582 年,教皇格里高利十三世发现现有的儒略历不足以反映现实,于是修改了闰年计算规则以应对这一问题。同样,公元 2013 年,Rockchip 的硬件工程师发现新的格里高利历仍有缺陷,认为 11 月应该算作 31 天。

    https://lwn.net/Articles/669022/

  3. adbachman

    几年前我在一个 Ruby on Rails 测试套件中遇到了这个问题,并在这里记录了我的发现:https://gist.github.com/abachman/f97806e1c0fe8e4e1849e5f8412...

    简而言之:ActiveSupport::TimeWithZone 使用绝对秒数计数来确定日期,而 DateTime 使用的是正确的格里高利历。这意味着在 1582 年 10 月 15 日之前的日期,两者的内部值在比较时会不同。

    这个问题之所以暴露出来,是因为某个测试使用 DateTime 值将 MySQL 的 DATETIME 列设置为数据库的最小值(即 1000-01-01 00:00:00),然后将数据库记录中的属性与最初用于设置该值的变量进行比较。

    类似这样的代码:

    date = DateTime.new(1000, 1, 1, 0, 0, 0, 'UTC')

    record.update(happened_at: date)

    record.happened_at == date # => false

    当我写了一个循环,从 1000 年 1 月 1 日开始逐秒向前计数,直到对应的 TimeWithZone 和 DateTime 记录在 == 比较中返回 true 时,我才“发现”了这些缺失的格里高利历日期。

同日更多故事

2026-08-04