今天在微信朋友圈看到一个 iOS 日历的截图,里面显示 2 月有 31 号。当时的第一反应是 iOS 这代码质量不咋地啊,test case 没 cover 到吧。
然后我自己翻来翻去,找到 1582 年及以前 2 月是有 31 号的,然后就搜了下“iOS 1582 calendar”。然后搜到了这个页面: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/DatesAndTimes/Articles/dtHist.html#//apple_ref/doc/uid/TP40010240-SW1
NSCalendar models the transition from the Julian to Gregorian calendar in October 1582. During this transition, 10 days were skipped. This means that October 15, 1582 follows October 4, 1582. All of the provided methods for calendrical calculations take this into account, but you may need to account for it when you are creating dates from components. Dates created in the gap are pushed forward by 10 days. For example October 8, 1582 is stored as October 18, 1582.
看来 1582 年确实不太平凡,进一步搜索知道了两个新词:儒略历和格里历
简单的说我们现在用的日历就是格里历。但是在格里历出现之前( 1582 年 10 月之前)使用的是儒略历,而儒略历是单纯的大小月交替,所以 2 月是有 31 号的。因为儒略历误差太大,所以后来使用了格里历进行替代。而 iOS 也在格里历出现之后将日历从儒略历切换成了格里历。
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.