Wednesday, July 19, 2006

Linux/Unix,日历以及宗教

很久都没更新了,前一阵事忙,后来有次看到关于linux/Unix日历的小百科,有趣,想转来却发现居然blog系统有问题,这次总算发出来了。

在linux下执行cal 9 1752,会看到很奇怪的输出结果
$ cal 9 1752
September 1752
S M Tu W Th F S
1 2 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

就是说9月2日到14日之间的11天都蒸发了,windows下由于开始的纪年是1980年,所以看不到这个结果。这不是bug,而是8g。具体是与历法发展的历史有关。下面是转贴的一段文字:
--------
儒略日是由法国学者 Joseph Justus Scaliger (1540-1609)发明的, 名称可能是取自 Scaliger 的父亲, 意大利学者Julius Caesar Scaliger (1484-1558)。 天文学家已经用儒略周期为自 4713 BC 一月一日以来的每一天赋予了一个唯一的数字。 这就是所谓的儒略日(JD)。 JD 0 指定为 4713 BC 一月一日正午 UTC 到 4713 BC 一月二日正午 UTC 的 24 小时。

"儒略日(julian Day)" 与"儒略历(Julian Calendar)"不同。 儒略历是 Julius Caesar 在 45 BC 发明的。一直用到大约 1582 年, 这时各国开始使用罗马历法。在儒略历里面, 一年是近似 365 1/4 天 = 365.25 天。 这样大约每 128 年就有一天的误差。

不断积累的历法错误促使教皇格里高利十三世(Gregory XIII)按照与弥撒议会 ( Council of Trent)一致的精神改革了历法。 在罗马历法里,一年是近似 365 + 97 / 400 天 = 365.2425 天。 因此对应于罗马历法,大约要 3300 年,才会积累一天的误差。

近似的 365+97/400 是通过利用下面的规则, 规定每 400 年有 97 个闰年实现的:


每个可被 4 整除的年是一个闰年。
不过,可被 100 整除的年不是闰年。
但是,可以被 400 整除的年还是闰年。


因此,1700,1800,1900,2100 和 2200 年都不是闰年。而1600,2000,和 2400年是闰年。 相比而言,旧式的 Julian 历法里面只有能被 4 整除的年是闰年。

1582 二月,罗马教廷要求从 1582 年十月减去十天, 因此1852(应为1582)年十月四日后面紧跟着就是十五日。 在意大利,波兰,葡萄牙 和西班牙都这样处理了。 其他天主教国家也很快跟着这么做了,但是新教国家不愿意修改, 而且希腊等东正教国家直到20世纪初才修改。 这个改革在英国及其殖民地(包括现在的 USA)在 1752年执行了。 这样 1752 年九月二日后面跟着 1752 年九月十四日。 这就是为什么 Unix 系统的cal生成下面的输出:

$ cal 9 1752
September 1752
S M Tu W Th F S
1 2 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

注意: SQL 标准声称 "在日期时间字面'datetime literal'的定义上, '日期时间(datetime)值' 中的日期和时间根据罗马历法受自然法则的约束 "。 在 1752-09-03 和 1752-09-13 之间的日子, 尽管被罗马教廷的教令取消了,但为了和 "自然法则"相一致,因而是有效的日期。

在世界的不同的地方,发明了许多不同的历法,有许多比罗马历法系统还早。 例如,中国历法的最早应用可以追溯到公元前14世纪。 传说黄帝在 2637 BC 就发明了这个历法。 中华人民共和国使用罗马历法用于民用。中国历法用于决定节日/节气。

----
补充:事后,好事者发现emacs中的日历却没有这特点,还专门发信去问。得到的答复是,没有问题,因为作者认为(应该不是那长得特麻原彰幌的Richard Stallman)作为同一种日历是不该出现这种跳跃的,比如我如果采用格利高里历法,那么每一天都是按照此历顺推。日期中的跳跃,应该只在改变历法的时候才会出现,这话也有道理。所以说这毕竟还是公说公有理,婆说婆有理的事情了。

----


中学的时候,对历法的“研究”很是痴迷,起因正是对编程的爱好。小学时到一师兄家里,他家有一台PC1500的袖珍电脑,上面带小打印机的那种,打印纸宽度就和现在商店里打印的收据差不多,不过纸的质量好得多。师兄编程给我打了一个日历,印象中月份用彩笔画出来,整个日历就一长条,但很好看。于是我就被毒害了,当时觉得自己设计程序,听着很神圣的样子,而似乎能打印日历就是编程的最高境界了。而后来我上初一,用的微机课本,最后一个大的project就是讲如何打印任何一年的年历,更加深了我的印象。

到了初中那年暑假,正是闲着,父亲单位上也配了这种袖珍计算机,父亲有时候用他打印一些简单的开方表什么的。到了我手里可就成了宝贝了,我还弄到一本详细讲解PC1500编程的宝典。暑假里就想自己写一个可以打印任何一年年历的程序。阳历是很快就写出来了,问题是雄心勃勃的我还希望能加上中国的传统节日和阴历。其实阳历的计算很简单,就是用365.2425天就可以搞定,但任何一年的阴历就很复杂了。当时一直没有办法找到任何关于阴阳历转换的算法资料,后来就只好作罢。这事情在幼小的心灵里形成了一种叫情结的东西。后来我大四的时候还想起来这事情,有网络在手,第一想法就是去搜,这才发现阴阳历的转化好象比我想得要困难一些。当时还在北大学报上搜到一篇关于阴阳历转换的文章,真没想到原来这还是一坑,可以在北大学报上灌水呢。

0 Comments:

Post a Comment

<< Home