设为首页收藏本站

爱吱声

 找回密码
 注册
搜索
查看: 8390|回复: 33
打印 上一主题 下一主题

[科普知识] 程序员的历法

[复制链接]
  • TA的每日心情
    开心
    13 小时前
  • 签到天数: 3060 天

    [LV.Master]无

    跳转到指定楼层
    楼主
    发表于 2015-2-1 18:10:26 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    本帖最后由 heinsect 于 2015-2-1 18:13 编辑 / n/ ]0 ?+ N5 m& m! {
    # i+ S: S" Z' D4 Y# P
    程序员计算日期是用儒略日的。
    7 ~$ V$ e# Z3 q) G, O6 T  M6 \/ i, r
    儒略日中的儒略和儒略历中的儒略的关系嘛,只是因为儒略日的发明人的爷爷葱白凯撒,给儿子用了大帝的名字。刚好儒略历也用了大帝的名字。
    9 o9 ~" N, h& i- B* I5 v
    + N( d% Q2 D& N4 H0 [: R% J! j; c单用日期的话,儒略日是从某天开始的一个日的整数。两个儒略日的差值就是相差的天数。这样想计算两个日期间的差值,计算星期几就很简单了。至于那个开始日期,儒略日的零点,用起来的时候谁也不关心,我就不讲了。: d0 e4 f6 C9 m& E7 ^# [9 C- R3 @

      p5 b5 w5 e  O' b9 E从格里高利历日期算儒略日(JDN)的公式是这个样子的:
    6 }" n$ X3 W- o0 O/ |- Y0 U
    ( l7 x2 I" [9 _先要改一下年月:
    2 k( [; K: C6 B0 |5 l# w2 M
    1 r2 K9 l5 I3 O3 t/ @7 m1 J3 P/ ^9 }" R& G  Z2 w
    上面这组公式的结果呢,差不多是这个意思:
    # B1 X% V* s0 B) ?$ J1 ~三月 m = 0, y=y
    ! c& p! b+ |7 F/ l! V5 [..., r% P7 D- n1 H9 Y: Z- W
    十二月 m=9, y=y
    1 M. @: E8 I- }0 _" x' _$ B0 t一月 m = 10, y=y-1+ F. c9 L; m9 o& K; `9 m3 X% m% l
    二月 m = 11, y=y-1
    5 u1 c& K; O! T; F( Y9 j: E
    ( d. V8 f3 m) y& |, j% z那个4800,是个计算零点,大概在公元前4801年,是和前面所说的那个零点相关的。
      y/ y3 C: S, F+ X- k  r/ }然后计算儒略日的公式长是这个样子的:
    6 d/ ^/ }, x2 e* R. A) Y9 Q( x+ B- b8 H$ K. u, e( @( C

    ' m1 O& n; G% a* {8 ?7 g* z2 V, B0 U2 @
    这个公式中最巧的部分是 floor((153m+2)/5), 做出的效果嘛,看这个表:2 e3 I7 b3 j5 V; [: Z. A
    Mar–Jul:31 30 31 30 31Aug–Dec:31 30 31 30 31Jan–Feb:31 28
    * B4 [2 O7 f: F最后面的那个系数,是相对于原点的修正值。原公式算出来的值一般太大,计算中用起来会超过32/64位字长。现在天文计算中一般会选择2000年1月1日为零点,之前有用1900年和1950年的。8 ]2 K9 O0 n( ^
    + B6 w6 p  s  d7 q
    从儒略日计算星期几,(JDN+1) mod 7 就好了。4 `* J% P, C9 ?) W$ h/ V5 ^
    % n1 D9 |) I* Q. j$ ^- M& p# x6 F
    这个公式是怎么来的呢? 1582年,教皇格里高利十三(XIII)发现,那一年的春分是3月11日,和儒略历里规定的日期3月21日差了十天。原因嘛,就是回归年的长度是365.2422,儒略历用的365.25。格十三用上了全部的指头,哦,应该是找了很多XX家之后,下令当年10月4日的后一天是10月15日,同时规定在原先四年一闰的基础上,100的整数倍年不是闰年,但400的整数倍年又是闰年。新的历法改名为格里高利历。
    3 F; A, D. N3 X$ H/ n: Q! o( v1 L/ H5 y/ y% _
    为了计算转换儒略历和格里高利历,一个法国的教会学者Joseph Justus Scaliger给出了这个公式。“儒略日”中的儒略,是他老爸的名字。4 O2 g. I# k  Z- H. l, D8 V
    : @% l  t7 ]- V7 ~8 ?3 d2 V
    哦,原来的文献中用的是儒略历日期,要算儒略日是这样的:# S& V; a9 k/ |  x8 w- Q; Y
    9 @8 z( h# D. P* m7 t
    # r( h$ A) \- k$ W4 G3 ~6 M. {

    ( S) X- ^/ [" O1 w9 f3 H: W从儒略日转格里高利历,也有一组公式,这里有:
    * C9 ~* k2 [1 j' v, Y6 C9 i8 u% _9 x, o
    其实这些偏差,在儒略历启用之前是有人知道的。但是,始皇三十五年的某一天,一个罗马士兵在西西里岛上,拔出刀来,朝一个老人身上刺下去。这一刺,西方的科技文明停滞了一千多年。来自群组: 软件人家

    评分

    参与人数 6爱元 +35 学识 +5 收起 理由
    东张西望 + 10 + 5
    懒猫猫 + 8 不明觉厉
    水风 + 3 谢谢分享
    东湖珞珈 + 4 谢谢分享
    马鹿 + 8

    查看全部评分

  • TA的每日心情

    2020-3-6 00:28
  • 签到天数: 564 天

    [LV.9]渡劫

    沙发
    发表于 2015-2-1 19:18:36 | 只看该作者
    不明觉厉,捞分走人

    点评

    也捞一分~  发表于 2015-2-3 12:24

    该用户从未签到

    板凳
    发表于 2015-2-1 20:21:47 | 只看该作者
    程序员为啥不直接用格历?
  • TA的每日心情
    开心
    前天 16:46
  • 签到天数: 2734 天

    [LV.Master]无

    地板
    发表于 2015-2-2 01:20:49 | 只看该作者
    蛮夷的国家成了黑社会渊薮,大科学家的故乡开始赖账

    点评

    哈哈哈哈~  发表于 2015-2-2 02:31
  • TA的每日心情
    奋斗
    7 小时前
  • 签到天数: 2948 天

    [LV.Master]无

    5#
    发表于 2015-2-2 03:00:26 | 只看该作者
    不明觉厉
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    2024-3-8 05:45
  • 签到天数: 2441 天

    [LV.Master]无

    6#
    发表于 2015-2-2 07:17:10 | 只看该作者
    N多年前学习BASIC语言的时候,就是用这个公式做核心计算,然后再加上几重循环控制的排版,打印一个当年的日历出来。
  • TA的每日心情
    开心
    2022-4-16 03:01
  • 签到天数: 192 天

    [LV.7]分神

    7#
    发表于 2015-2-2 09:53:15 | 只看该作者
    假装我看懂了,然后评分
  • TA的每日心情
    奋斗
    2020-8-27 18:47
  • 签到天数: 638 天

    [LV.9]渡劫

    8#
    发表于 2015-2-2 11:27:07 | 只看该作者
    能换算干支就更好了。
  • TA的每日心情
    开心
    2023-1-5 00:48
  • 签到天数: 2591 天

    [LV.Master]无

    9#
    发表于 2015-2-2 13:09:09 | 只看该作者
    看来俺一定不是程序员了,因为俺从来就没这么复杂地玩过。日期可以从系统函数或者类库中的方法得到,我最多只需要计算某年是否是闰年就足够了。
  • TA的每日心情
    慵懒
    2026-4-20 10:14
  • 签到天数: 2868 天

    [LV.Master]无

    10#
    发表于 2015-2-2 13:52:01 | 只看该作者
    老兵帅客 发表于 2015-2-2 13:09) R! H/ [' I/ d- ?7 D
    看来俺一定不是程序员了,因为俺从来就没这么复杂地玩过。日期可以从系统函数或者类库中的方法得到,我最多 ...
    / ~: V! f# i' E9 M  A( n
    试试计算下一千年每年复活节是哪一天,我又得昏过去了。。。哈哈哈。。。
  • TA的每日心情
    开心
    2022-12-1 00:01
  • 签到天数: 2488 天

    [LV.Master]无

    11#
    发表于 2015-2-3 01:49:06 | 只看该作者
    老兵帅客 发表于 2015-2-2 13:09
    6 a/ Z) {8 k* m# E4 w( `7 \2 Q看来俺一定不是程序员了,因为俺从来就没这么复杂地玩过。日期可以从系统函数或者类库中的方法得到,我最多 ...
    ' U% Z4 P  T8 ?4 }; N
    这个在当年可以用的日期函数还很罕见的时候有用。后来系统本身就提供这些计算了,自然没必要记。
    ( H# W: U/ x. J4 [
    4 _* r7 {/ \, y2 s$ f3 C. p我最早见到也是学BASIC的时候。/ ^6 a! [, [* |8 x& e0 k4 J, @
    & m: E% g, V* z/ o1 w; @
  • TA的每日心情
    开心
    2022-12-1 00:01
  • 签到天数: 2488 天

    [LV.Master]无

    12#
    发表于 2015-2-3 01:53:29 | 只看该作者
    本帖最后由 橡树村 于 2015-2-3 01:55 编辑 7 R( e# @  I( h' \6 B% j' n
    hotmen 发表于 2015-2-2 11:27
    ( q9 U! ?4 q2 w8 a* i+ ~3 b* Q能换算干支就更好了。

    7 N; c. x/ y' p3 Q9 c" s
      W' U& V4 V: E; F: S计算干支里面的日期不难,时辰是从日期推算的,也不难。
    % F& c& U, E5 U& l: r1 b月份是按照年来推算的,说起来简单,难点在于一年以及一个月的开始时间的计算。这个很难有通用公式。不过还是比农历要简单,干支记年实际上是阳历,每年开始于立春,然后每间隔一个节气就换一个月,与农历的月份并不相同。这样只要有了节气的准确时间数据库,干支的问题也就解决了。
    . h. C4 N! t+ ~; ?  H$ a
    + c; O8 R+ l, h! x9 i. Y农历复杂在于,这个历法经常被改动,要准确把历史上的某一天与西历进行换算,需要把曾经使用过的历法都考虑进去,这个麻烦就大了去了。而且每个月的开始取决于月亮的朔望,这就更要把历史上月亮的运行轨道都考虑进去了。
    3 F, Z9 e' ]2 b* v& k; ]
    " ]( N# S; n+ n5 i. S* F9 X
  • TA的每日心情
    开心
    2023-1-5 00:48
  • 签到天数: 2591 天

    [LV.Master]无

    13#
    发表于 2015-2-3 02:13:12 | 只看该作者
    橡树村 发表于 2015-2-2 12:494 p2 V/ K/ o! f2 `6 h
    这个在当年可以用的日期函数还很罕见的时候有用。后来系统本身就提供这些计算了,自然没必要记。
    ' C) b/ K8 ~  M1 e  G8 u" M0 Q+ x/ @  g/ i+ b  I/ v% X3 s
    我最早 ...

    1 `$ B2 L6 C& v: K3 C0 v+ @  R+ I: I& t问题是DOS下面的BASIC已经提供日期函数了啊,程序员何必再用这个?
  • TA的每日心情
    开心
    2022-12-1 00:01
  • 签到天数: 2488 天

    [LV.Master]无

    14#
    发表于 2015-2-3 02:21:35 | 只看该作者
    老兵帅客 发表于 2015-2-3 02:13, r! L% f0 G* U8 L, A, O0 ~
    问题是DOS下面的BASIC已经提供日期函数了啊,程序员何必再用这个?
    5 z/ h5 ?4 M: k, H4 ~$ l9 z
    不记得当年BASIC有计算两个日期之间有几天的函数。也许有但从来没用过,当年就没有使用BASIC做过这类编程,最多弄个日历啥的。
  • TA的每日心情
    开心
    2023-1-5 00:48
  • 签到天数: 2591 天

    [LV.Master]无

    15#
    发表于 2015-2-3 02:29:31 | 只看该作者
    橡树村 发表于 2015-2-2 13:21
    8 p6 o" Z6 U% l+ C7 ~不记得当年BASIC有计算两个日期之间有几天的函数。也许有但从来没用过,当年就没有使用BASIC做过这类编程 ...

    , k% a" m  v( g$ v我当年学PASCAL的时候,一个作业就是编万年历,从你的当前日期开始。因此我们就用PASCAL自带的日期函数找出当前日期,然后自己计算闰年。计算闰年的算法很简单的,远比楼主的简单。
  • TA的每日心情
    开心
    2023-1-5 00:48
  • 签到天数: 2591 天

    [LV.Master]无

    16#
    发表于 2015-2-3 02:29:44 | 只看该作者
    橡树村 发表于 2015-2-2 13:21: u: w* m* Y' T) L( J, y# z
    不记得当年BASIC有计算两个日期之间有几天的函数。也许有但从来没用过,当年就没有使用BASIC做过这类编程 ...

    0 Q& n) a0 m: p  q) g" U. ~我当年学PASCAL的时候,一个作业就是编万年历,从你的当前日期开始。因此我们就用PASCAL自带的日期函数找出当前日期,然后自己计算闰年。计算闰年的算法很简单的,远比楼主的简单。
  • TA的每日心情
    开心
    2022-12-1 00:01
  • 签到天数: 2488 天

    [LV.Master]无

    17#
    发表于 2015-2-3 02:42:02 | 只看该作者
    老兵帅客 发表于 2015-2-3 02:29
    / h2 P  E9 O% _我当年学PASCAL的时候,一个作业就是编万年历,从你的当前日期开始。因此我们就用PASCAL自带的日期函数找 ...
    4 q3 f0 X- M. m
    Turbo Pascal?
    9 C" c/ [8 C- d" f( g" ^+ _+ F7 G3 x' F& c: W
    最早PC机带的BASIC函数很少的,和Pascal比不了。
  • TA的每日心情
    开心
    2023-1-5 00:48
  • 签到天数: 2591 天

    [LV.Master]无

    18#
    发表于 2015-2-3 02:44:42 | 只看该作者
    橡树村 发表于 2015-2-2 13:42
    & b8 d0 U/ q- [, g, C; w5 L3 dTurbo Pascal?" t6 Z5 E7 G  k- f9 Y7 b
    - ~! O6 k3 ]! F* z
    最早PC机带的BASIC函数很少的,和Pascal比不了。
    " R6 ]3 `" O) r: N6 O
    不,是标准PASCAL,用的是微软的编译器。我上学的时候还没出turbo pascal呢,后来这东西出来了,拿来一试,发现丫不兼容标准PASCAL嘿,于是再也没碰它。
  • TA的每日心情
    开心
    2022-12-1 00:01
  • 签到天数: 2488 天

    [LV.Master]无

    19#
    发表于 2015-2-3 02:52:31 | 只看该作者
    老兵帅客 发表于 2015-2-3 02:443 l- X. V. `: c; L
    不,是标准PASCAL,用的是微软的编译器。我上学的时候还没出turbo pascal呢,后来这东西出来了,拿来一试 ...

    , I' F8 V: c3 l- ]- C- W3 [) M; wTurbo pascal 是83年的,那时候我还不知道计算机长啥样呢。& r2 x% ^( G" c  T9 I

    9 ~: [1 G# s( r! R6 b我最早是在Comx35机器上接触的BASIC,84年。

    评分

    参与人数 1爱元 +4 收起 理由
    七月群山 + 4 伙呆了

    查看全部评分

  • TA的每日心情
    奋斗
    2024-3-8 05:45
  • 签到天数: 2441 天

    [LV.Master]无

    20#
    发表于 2015-2-3 04:01:00 | 只看该作者
    橡树村 发表于 2015-2-3 02:52
      Y4 [! x2 T3 b! J' v- `8 U0 I$ YTurbo pascal 是83年的,那时候我还不知道计算机长啥样呢。4 I3 n; Q5 V! b

    ; a  c' ~% j1 b( J. i1 E7 f. f0 t我最早是在Comx35机器上接触的BASIC,84年。 ...
    7 Y- c, a% B% C3 h0 F
    村子老资格啊

    手机版|小黑屋|Archiver|网站错误报告|爱吱声   

    GMT+8, 2026-5-18 13:30 , Processed in 0.069846 second(s), 18 queries , Gzip On.

    Powered by Discuz! X3.2

    © 2001-2013 Comsenz Inc.

    快速回复 返回顶部 返回列表