Daily Tech Briefing
AI 科技速览

每天 5 分钟内学习 AI。获取最新的人工智能新闻,理解其重要性,并学习如何将其应用于您的工作。

AI 快讯
Hacker News · 2026/8/1 17:18:48

Dates That Don't Exist (2015)

AI 中文解读
你知道吗?1582年10月5日到14日这十天,在历史上根本不存在。当时为了修正日历偏差,教皇直接下令跳过这十天,人们10月4日睡觉,醒来就是10月15日。这篇新闻最有趣的地方是:当程序员想用代码创建这个“不存在的日期”时,不同编程语言给出了截然不同的反应——Ruby会直接报错拒绝,而Python却“坦然接受”,甚至能正常显示。这暴露了一个隐藏问题:现代软件虽然天天处理日期,但很多程序的日历逻辑并不严谨,遇到历史上真实的日期调整就可能出错。对普通人来说,这可能影响银行利息计算、合同日期分析、历史数据统计等场景。比如你要查询某个历史事件发生在星期几,用不同工具可能得到不同答案。虽然大多数人一辈子不会遇到1582年,但这提醒我们,看似简单的日期处理,背后藏着复杂的历史细节,而软件工程师需要更谨慎地对待这些边界情况。
ENOSUCHBLOG Programming, philosophy, pedaling. Home Tags Series Favorites Archive Main Site TILs Mini-post: Dates That Don't Exist Jun 9, 2015     Tags: programming     This post is at least a year old. Calendars and Missing Dates# In 1582, under the inter gravissimas papal bull, the Catholic world transitioned from the Julian Calendar to the Gregorian Calendar. This new calendar shortened the length of the year from 365.25 days to 365.2425, a reduction of just 0.002%. One side effect of this is the modern leap year system, in which every fourth and 400th year is a leap year, but no other year divisible by 100 is. For example, this means that 1900 was a normal year, 1904 was a leap year, and 2000 was also a leap year. Another side effect (and the topic of today’s post) was that the Julian and Gregorian calendars no longer agreed on the date. Calculating each from 1 to to 1582 AD, the Julian calendar had slowly accumulated “drift” relative to the Gregorian calendar, lagging eleven days behind it. To correct for this drift, ten days had to be removed from the 1582 year, converting the entire system from Julian to Gregorian. Selecting an appropriate 10-day span took nearly 20 years (owing in no small part to the Catholic church’s reluctance to skip any holidays and desire to correct the Easter drift), but eventually the span of October 5 to October 14 was chosen. The end result? On the fourth of October, 1582, citizens of the Catholic world* went to sleep and woke up ten days later, on the fifteenth of October, with a new calendar. In essence, then, those ten days in 1582 never happened and simply do not exist within the Gregorian calendar system used almost universally in the West today. So, how well do programming languages handle this range of dates? Ruby# Right off the bat, Ruby does the right thing - it simply does not allow a DateTime with an impossible Gregorian date to be created: 1 2 3 4 5 6 7 irb(main):001:0> require 'date' => true irb(main):002:0> DateTime.new(1582, 10, 5) # October 5, 1582 ArgumentError: invalid date from (irb):2:in `new' from (irb):2 from /usr/bin/irb:12:in `<main>' This can be traced to the datetime_s_civil function in ext/date/date_core.c: 1 2 3 4 if (!valid_gregorian_p(y, m, d, &nth, &ry, &rm, &rd)) rb_raise(rb_eArgError, "invalid date"); Python# Python’s datetime module, despite claiming to represent a date object in “the current Gregorian calendar,” sadly does not do so: 1 2 3 4 5 6 7 8 Python 2.7.6 (default, Mar 22 2014, 22:59:56) [GCC 4.8.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> from datetime import date >>> date(1582, 10, 5) # October 5, 1582 datetime.date(1582, 10, 5) >>> date(1582, 10, 5).ctime() # October 5, 1582 'Tue Oct 5 00:00:00 1582' This is the case for both Python 2 and Python 3. Perl# Perl has no standard analog to Ruby’s DateTime or Python’s date, so I opted for the common DateTime module from the CPAN instead. Unfortunately, like Python, a proper error message for impossible Gregorian dates is notably absent: 1 2 3 4 5 6 7 #!/usr/bin/env perl use DateTime; my $dt = DateTime->new(year => 1582, month => 10, day => 5); print $dt->ymd('/'), "\n" This example runs without error (which is the error) on Perl 5.18, with DateTime 1.19. Summary# Despite the fact that dates between the 5th and 14th of October in 1582 are impossible to represent on the Gregorian calendar, two out of the three languages tested allow programmers to create “Gregorian” dates for those days. This is certainly no Y2K or Unix epoch problem, but it’s a good indicator of how far we’ve come with respect to plain and simple correctness in date and time implementations. Even if it means adding an extra check to make sure that nobody creates a date within a
分享
阅读原文