今天在微信朋友圈看到一个 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 也在格里历出现之后将日历从儒略历切换成了格里历。
1
dimlau 2020-01-07 21:38:22 +08:00 1
原来在 1582 年之前苹果公司一直是用儒略历的啊。
|
2
billlee 2020-01-07 22:30:38 +08:00
第一次知道格里高利历是因为 Java 把 timestamp 转换成日期要显式调用 GregorianCalandar
|
3
AlphaTr 2020-01-07 22:57:47 +08:00
|
4
beimenjun 2020-01-07 23:07:30 +08:00
呃,你说的有点问题,因为格里历的历年一年是长度为 365.2425 日,而儒略历的年就是 365.25 天。儒略历运行久了,冬至啦夏至啦都会慢慢被延后,因此才改历的。(格里历闰年计算规律是四年一闰,而实际上我们现在的设定是“四年一闰,百年不闰,但四百年闰”的闰年计算规律是更符合天体运转的)
所以其实只是 2 月是不是闰年的区别,没有什么 2 月 31 日的……闰年也是 29 天。 |
5
jadec0der 2020-01-08 00:00:29 +08:00
我第一次听说这个是因为 Java 的 date 对 1582 之前的日期有特殊处理
|
6
geelaw 2020-01-08 07:29:02 +08:00
只有我一个人想知道为什么 3、8、12 月都下沉了吗
|
7
Deepseafish 2020-01-08 18:33:38 +08:00 1
|