免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12345
最近访问板块 发新帖
楼主: sohu2000000
打印 上一主题 下一主题

[C] [原创] C语言实现:万年历 [复制链接]

论坛徽章:
0
41 [报告]
发表于 2010-09-07 01:48 |只看该作者
回复 38# wzl7222504


   
==!两点都有点误解,第一重点是全局变量,第二重点是基姆拉尔森计算公式,而不是算闰年
话说最近搞jav ...
wzl7222504 发表于 2010-09-04 23:20



   关于第一点:  我个人真滴不是很喜欢全局变量,我有点嫌它污染变量名称空间,不知道你为什么推荐用它?可不可给我们讲讲呢?
  
  关于第二点:  真滴木有接触过“基姆拉尔森公式”,所以可能木有理解你回帖的真正含义,立正给大家道个歉,马上上网去补习,也来汗一个~~~  {:3_204:}

论坛徽章:
0
42 [报告]
发表于 2010-09-07 01:56 |只看该作者
回复 39# 幻の上帝


   
Gregorian历当年好像也就五个国家承认,其它国家用得稀里糊涂的,像乔治·华盛顿出生日之类的日期有两个... ...
幻の上帝 发表于 2010-09-05 19:43


      我这两天一直在前面的那个朋友的提示下去查农历的算法,搞得头大,真是晕菜了,后来还出现什么“润八月”,什么“自然天体现象”。。。。。现在偶连《易经》都搬出来了在班车上看,
想找找老祖宗们是怎么靠八卦算的(本来想的是八卦--用8或者64做模来计算滴~~~)。 今天才发现自己的NOKIA手机上面的日历有农历,正打算赶紧请教NOKIA的朋友,不知道一斤白酒够不
够... ...
    我尽量快点去想办法,如果万一米有搞得,也请大家见谅~~~~
      兄弟,多谢你的提示啦,我去农历网上看看去  :)

论坛徽章:
0
43 [报告]
发表于 2010-09-07 01:58 |只看该作者
回复 34# benjiam


   
没仔细看 但是你应该没解决闰月问题。

因为太阳时间和地球本地时间每年的差别,所有每4年多了1天多。 但 ...
benjiam 发表于 2010-09-02 10:04


    兄弟,能帮着将细致点么,多谢啦

论坛徽章:
0
44 [报告]
发表于 2010-09-07 10:26 |只看该作者
http://tieba.baidu.com/f?kz=802504159


公历和农历由来 历史上"丢失"的10天

    *
    * 飞飞亦飞飞
    * 0位粉丝
    *

       

1楼
公历和农历由来 历史上"丢失"的10天:1582年月10月5日至1582年月10月14日

以回归年周期为主要依据所编制的“太阳历”  

太阳历又称“阳历”。它不考虑月相的变化如何,只考虑地球绕日公转一周即一个回归年的时间长短。我们知道,地球总是斜着身子绕日不停地作圆周运动,公转一周的时间是365.2422日(即365天5时48分46秒)。如果人为地设置十二个月,小月为三十天,大月为三十一天,仍然由于一回归年后有一个小数点尾巴带来的问题。后来人们又想出了设置闰年的办法来解决这个问题,譬如平年365天,闰年366天,以便保证阳历年的长度与实际回归年的长度基本吻合。  

与西汉王朝同时代的古罗马帝国也是文明古国之一,曾经使用的是以朔望月为依据的阴历,后来为了协调与回归年的关系,采用了各种设置闰月的办法,但始终是一个混乱无序的“阴阳历”。公元前四十六年,儒略.恺撒掌握军政大权后,聘请了天文学家索西琴改革历法,其要点是:  
1、全年十二个月,单月为大月三十一天,双月为小月三十天,平年的二月为二十九天,全年共计三百六十五天,  
2、冬至后十月为一年的开始,即为每年的岁首。  
3、从改历的下一年起,每三年是一闰年,闰年共计三百六十六天,所多的一天放在二月尾,为三十天。  

这就是现行流行的阳历的前身,一般称“儒略历”,其中七月因儒略.恺撒的出生而命名为“儒略月”。然而负责执行的僧侣们误把“每隔三年置一闰年”理解为“每三年置一闰年”,并一直错误执行了三十多年,到公元前九年屋大维(即奥古斯都)统治时,人们发现三十多年中已多设置了闰年五次,于是屋大维下令在以后的一段年份里少设三次闰年,并恢复原来每四年设置一闰的规定。屋大维是把自己的出生的八月命名为奥古斯都月,于是把原来属于小月的八月改为大月,多出的一天从二月中扣出。同时,为了避免一连三个大月,又把九月和十一月改为小月,十月和十二月改为大月。这一不合理的规定一直延续到现在。  

儒略历规定每年平均长度是365.25天,比实际回归年长出0.0078天,即每年长出12分14秒。这点差值在短期内难以发现,但只要过128年,历法规定的年就要多出回归年一天,公元325年,至高无尚的的欧洲基督教教会召开宗教大会,一致确定儒略历是最准确的历法并全面推行。并根据天文观测和宗教活动的需要,规定春分日必须是三月二十一日,而纪念耶稣死后复活的复活节定在春分满月后的第一个星期日,到公元1582年,随着哥白尼太阳中心说的确认和天文观测的技术的进步,发现实际春分时刻已提前到三月十一日,比原定的三月二十一日提前十天,当时的罗马教皇格列高列十三世便召集天文学者和僧侣们商讨改历问题,最后决定采用天文学家利里奥的改革方案。  

1、为使春分时刻再回到三月二十一日,把1582年月10 月4日以后的一天改为10月15日,从中删去10天。  
2、采用400年97闰法,即凡公元年号能被4整除为闰年,但公元年号为整百年时,须能被400整除者方为闰年,(如1600年、2000年)。其它为平年(如1700年、1900年)。  

这就是目前世界上通用的阳历,又称“格列历”。至于岁首和纪元的设置,也是人为而定。现在的岁首是儒略.恺撒颁布历法时规定的,即定在冬至后十天为一月一日,因此有“冬至十天阳历年”的说法。古代欧洲和我国过去一样常采用“王位纪年法”,即将某个统治者登基作为纪年的开始,在西欧的罗马帝国则以罗马统治者狄奥.支列颠称帝时作为纪年的开始。后来有个叫狄奥尼亚的基督僧侣在预先推算狄奥支列颠纪元248年的“复活节”日期时,提出所谓耶稣诞生于狄奥.支列颠纪元前284年的说法,并主张以耶稣诞生的一年为纪元。它的主张竟然得到教会的大力支持,这样,狄奥支列颠248年就成为耶稣诞生纪年的532年。因此,现行的公历纪年,实际上从公元 532年才在一些地区开始实行,到现在逐步成为全世界通用的正式纪年.

独具特色的我国农历  

与现行阳历并用的农历,一直是我国的传统历法,也是我国古代以来农民安排农事活动的重要依据。因此,称之为“农历”。其大致的做法是:  
1、朔望月周期是29.5306天,因此农历规定大月三十天,小月二十九天,但大小月并不因定顺序,而是由两次合朔之间的天数来决定。前提为凡是有合朔时刻的一天,必定为初  
2、若一年为十二个月,共计354天多,比实际回归年少11天多,长此下去月序与节令气候不吻合,因此采取设置闰月的办法来调整。大概在春秋时代采用“十九年七闰的办法,即每十九年,插入七个月,一般还把不会“中合”的月份定为闰年(二十四节中,单数则叫“节气”,双数则叫“中气”。)  

二十四节气是我国劳动人民的一个创造。它能准确地反映太阳在黄道上的位置,生动地体现了地面上寒暑四季变化的循环规律,同时也具有鲜明的节气特点和浓郁的乡土气息,主要是黄河中下游地区。共顺序依次是:立春,雨水,惊蛰,春分,清明,谷雨,立夏,小满,芒种,夏至,大暑、小暑、立秋、处暑、白露、秋分、寒露、霜降、立冬、小雪、大雪、冬至、小寒、大寒。从它的含义上看,有反映天象的,如立春、春分、立夏、夏至、立秋、秋分、立冬、冬至,其中夏至和冬至是太阳直射点分别在北回归线和南回归线的时刻,而春分与秋分时太阳直射点均在赤道上。也有表示气候的,如雨水、清明、谷雨、小暑、大暑、处暑、白露、寒露、霜降、小雪、大雪、小寒、大寒。还有表示物候的,如惊蛰、小满、满种等。下面根据二十四节气编成的谚语能反映出节气与农事安排的关系。如“立春耕牛走”,“清明种瓜豆”,“谷雨播大田”,“小满粒长满”,“芒种忙收种”,“夏至秧苗全”, “处暑备也镰”,“小寒忙买办”,“白露谷登场”,“大寒要过年”,为了便于记记忆,二十四节气中每取一字,可能编成一首顺口溜。“春雨惊春清谷天,夏满芒夏暑相连,秋处露秋寒霜降,冬雪雪冬大小寒”。  

农历还有一套特有的纪年和纪日方法,就是所谓的“干支纪法”。干支即“天干”“地支”的总称,以甲、乙、丙、丁、戌、已、庚、辛、王、癸、申10个这字为“天干”,以子丑、寅、卯、辰、已、午、未、申、酉、戌、亥十二个字为“地支”,并让相应的天干与地支有序组合,便可得到60以不同的干支,60年一个循环,往复不断。到了近代人们习惯有用干支纪年来表明某些重要的历史事件,如 1894年的甲午战争,1898年的辛亥革命。干支纪法比较繁琐,此不评述。

因为这方面的原因,有些编程语言对这段时间的处理会出错,比如C#就会出错,下面就是示例代码:
C# code
using System;

class GregorianTest
{
     static void Main()
     {
         //消失的十天为1582年月10月5日至1582年月10月14日
         DateTime dt1 = new DateTime(1582, 10, 4);
         Console.WriteLine(dt1.ToString("dddd yyyy-MM-dd"));
         //按照道理加一天之后应该为1582-10-05了
         Console.WriteLine(dt1.AddDays(1).ToString("dddd yyyy-MM-dd"));
         //按照道路这一天应该不是1582-10-06了
         Console.WriteLine(dt1.AddDays(2).ToString("dddd yyyy-MM-dd"));
        
         DateTime dt2=new DateTime(1582,10,14);

Console.WriteLine(dt2.ToString("dddd yyyy-MM-dd"));
         //按理说不存在1582-10-13
         Console.WriteLine(dt2.AddDays(-1).ToString("dddd yyyy-MM-dd"));
         ////按理说不存在1582-10-12
         Console.WriteLine(dt2.AddDays(-2).ToString("dddd yyyy-MM-dd"));
     }
}

不过几乎很少有人会涉及到这个时间的编程,所以无需过多考虑。


在现在通行的历法记载上,全世界居然有十天没有任何人出生过,也没有任何人死亡过,也没有发生过大大小小值得纪念的人或事。这就是1582年10月5日至10月14日
持续时间为0的一年是什么意思?  
事实上,目前世界通行的公历中,就有持续时间为0的10天,即公元1582年10月5日至14日。事情是这样的:  
西方历法的第一次改革是罗马朱利乌斯·凯撒大帝于公元前45年亲自引进的。当时采用的数字是一年365.25天,于是朱利安历法成为最简单的历法:第一、二、三年都是365天,三年余下的0.25天给第四年,第四年就有366天,这就是闰年。于是重复365,365,365,366的周期,每年都是整数。  
但是,一个太阳年不刚好是362.25天,而是 362.242199…天,每年相差11分14秒,也就是朱利安历法中每年多算了11分钟14秒。由于误差不太大,头几年没什么关系,凯撒活着时影响还不大。但是,一年又一年,误差累积起来,朱利安历法就与实际的太阳年不合拍了。例如每年春分在3月21日前后,但几个世纪后,春分在朱利安历法上的日期越来越提前了,这对农民种地不方便,对教会确定复活节在哪一天也带来麻烦。由于朱利安历法是凯撒亲自制定的,上述情况对他的威信是一个沉重打击。  
16 世纪时,教皇格利戈里八世进行了一次校正。因为到16世纪,每年11分14秒已经累积成10天,也就是历法上多了10天,这对于确定复活节造成严重困难,不得不采取措施补救。为此,格利戈里采取了解决此类难题的最古老最有效的策略----他召集一个委员会,任命一位聪明的主席,即杰出的耶稣会数学家克利斯多弗·克拉维斯(Christopher Clavius),要求委员会提出解决方案。委员会于1587年开始工作。  
克拉维斯委员会面临两个不同的问题,它用不同的方法进行解决。第一,朱利安历法现在走快了10天,必须拉回到与太阳年一致。克拉维斯建议用官方声明把这10天抹掉!教皇格利戈八世于1582年2月24日以教皇训令颁布,将1582年10月5日至14抹掉,于是这10天就消失了,一去不复返。1582年10月4日过完了,第二天已经是10月15日了,于是历法又回到与太阳年同步。  
当时以及后来有许多人对此感到惊愕,目瞪口呆,有人认为是荒唐、武断。“教皇一纸训令就能抹掉日历上的10天?”  
但是,这10天的确不存在了,这10天什么也没有发生,这10天根本就没过日子。如果你能找到当时的日记,10月4日记完后,下一页就是10月15日的事。用科学语言表达,这10天的持续时间为0。  
其实完全不必惊讶。太阳年、太阳日与自然现象有联系,至于某一天是什么日子,则是人为的,与给小孩起名字一样。我们可以不用公历,一年不分月,只叫第1天,第2天,……第125天,……到第365天,这是允许的。喜欢偶数的人可以发明一个“偶数日历”:2月2日,2月4日……4月2日……12月30日,12月32日……,14月2日,这也是允许的,只要一年365 天或者366天就行。这再一次证明,在一个科学理论或体系中区分出由自然现象决定(因而必须符合实验)的部分和人为规定的部分是重要的。  
当然,这个决定对当时的社会生活也会有一定影响,例如出生在10月5日至10月14日的人在1582年找不到自己的生日,但与出生在2月29日的人相比,少过一年生日算不了什么。还有,那年10月份的工资、利息也会有问题,但不知那时的银行、工资制度什么样。不过这些问题与我们马上要遇到的千年虫问题相比,影响微乎其微。  
第二个问题是需要提出历法的补充规则,不让每年多出的11分14秒累积得太多。于是克拉维斯委员会提出一年有365.2422 天的方案,这比朱利安历法的365.25天大大接近天体运动实际。据此对朱利安历法只有“四年一闰”的简单规定进行校正:四年一闰,但是世纪之交的’00 年,如100年,200年,不闰,即每一百年少闰一次。这样一算,闰年又太少了,于是进一步规定:每四个世纪的世纪之交,即400年,800年等仍是闰年。最终关于闰年的规定为,用4除尽的年份仍是闰年。教皇训令也批准了这个校正。经过这两个校正的朱利安历法叫格利戈里历法,也就是我们现在用的公历。由于格利戈里历法中的年与太阳年仍有误差,还需要进一步校正,不过二者只相差25.96秒,每过2800年才相关一天,在实际生活中没什么影响。这样,1900年不是闰年,但将要到来的2000年是闰年,每400年才遇到一次!又一个特殊性!  
格利戈里历法很快在罗马天主教势力范围被普遍接受,但是在英国却引起了一片喧嚣的反对声,英国人仍然坚持朱利安历法,拒绝“抹掉10天”。直到1752年,英国人才想通,理性终于占了上风,不过从 1582年到那时,历法又多出了1天,所以英国议会在1752年作出决定,抹掉11天----1752年9月3日至13日,至此才接受了格利戈里的改革。请注意,英国历史中,这11天什么也没有发生。由此可以看到,一次历法改革是多么不容易,对于一个聪明、合理的决定,仅仅因为看上去有点怪就有人反对,竟然花了快二百年才接受!

论坛徽章:
0
45 [报告]
发表于 2010-09-07 10:42 |只看该作者
纯粹的太阳历问题不用涉及闰月。
----
关于格里历的使用,其实英国还算是比较清楚的……
(以下转自喂鸡...)
天主教国家以外的采用

格里历1582年10月15日,合儒略历1582年10月5日,只有意大利、波兰、西班牙、葡萄牙开始用格里历,日期跳过10日。由于新历法是教皇颁布的,新教国家予以抵制。直到18世纪,大英帝国,包括英格兰、苏格兰、以及现在美国的一部份才采纳格里历,也就是儒略历 1752年 9月2日星期三的次日是格里历1752年9月14日星期四,日期跳过11日。


值得注意的是,1582年,罗马教廷减去的是10天,而到1752年修改历法的时候却减去了11天的原因其实很简单,这涉及到了闰年的问题,闰年的计算方法:公元纪年的年数可以被四整除,即为闰年;被100整除而不能被400整除为平年;被100整除也可被400整除的为闰年。而1600年和1700年的2月都是29天,原来在1800年之前的闰年计算方法中没有把被100整除而不能被 400整除的年份算为平年,更没有考虑到被100整除也可被400整除的算为闰年。所以罗马教廷把1700年的2月算成29天,而1600年的2月却是阴差阳错地恰好与现行的历法相符。结果1582年到1752年之间,当时历法算法和现行历法算法实际只相差了1天。

在阿拉斯加,儒略历 1867年10月6日星期五的次日是格里历10月18日星期五。之所以连续二日星期五是因为“阿拉斯加时刻”从“亚洲时刻”改成“北美时刻”,使得国际换日线从阿拉斯加之东移往之西。此事是因为美国从沙俄买入阿拉斯加,并发生在创造时区之前。

瑞典在1699年有计划从儒略历改成格里历,但预定的办法是取消自1700年至1740年原有的11闰日,即2月29日,以期求渐进在最后将日期与格里历接轨。在此四十年间,瑞典历与儒略历以及格里历日期将完全不同。此制度明显足以使得此期间的瑞典事件发生在何日记录不易的困扰。更糟糕的是,此制度施行不佳,而1704年及1708年应已排除的闰日仍被使用。此时瑞典历日期应比格里历慢8日,但事实上是慢10日。卡尔十二世国王承认渐进改历没有见效而抛弃之,但不是直接改用格里历,而是决定改回儒略历,方法是1712年2月29日的次日加上2月30日,日期再度比格里历慢11日。瑞典最后在1753年采用格里历,就是当年儒略历 2月17日星期三的次日是格里历3月1日星期四。

俄罗斯在1917年发生的十月革命(开始于儒略历10月25日,合格里历11月7日)后,以1918年1月24日的命令接受格里历,也就是儒略历1918年1月31日 星期三的次日是格里历1918年2月14日 星期四。

最后采用格里历的国家是土耳其,1926年。

伊斯兰教国家仍然使用伊斯兰历;佛教国家采纳佛教历,纪元使用佛教纪元,即公元2000年为佛教纪元佛祖诞辰2544年。
[编辑] 东亚的采用

中国在1912年1月1日,中华民国成立时,以格里历取代传统的农历,定格里历为国历,但年份不使用公元纪年,另设民国纪年,以中华民国成立的1912年为首年,即中华民国元年等于1912年、中华民国二年等于1913年等(公元纪年减1911,即等如民国纪年),“中华民国X年”一般简称为“民国X年”、“民X”。但中国不久后进入不同军阀使用不同历法的军阀割据时期。1928年10月国民党北伐统一中国,中华民国政府命令自1929年1月1日起使用格里历。1949年10月1日,中华人民共和国成立,取代中华民国统治中国大陆,继续使用格里历,但年份改以公元纪年。而中华民国退守台湾后,仍在其有效统治的台湾地区使用民国纪年,台湾民间亦常使用民国纪年,一直至今。

台湾于1895年(明治28年)成为日本殖民地,官方采用格里历。1919年改行格里历新年,但实际上日本人使用格里历,台湾人仍习惯使用农历。直到皇民化运动期间的1940年2月8日,台湾总督府公告废止农历新年,订农历新年起连续五日为“劳动服务周”。至1945年,台湾主权移交中华民国,继续使用格里历,但年份改用民国纪年。1955年,中华民国政府机关恢复农历新年休假[1]。

日本在1873年(明治六年)1月1日,以格里历取代传统天保历,但年份不使用公元纪年,而使用日本天皇年号纪年:明治元年等于1868年,大正元年等于1912年,昭和元年等于1926年,平成元年等于1989年,一直至今。民间常使用公元(西暦, seireki)纪年,但政府较少使用之。

朝鲜受到日本影响,在1896年1月1日采用格里历。[2]

论坛徽章:
0
46 [报告]
发表于 2010-09-07 10:50 |只看该作者
东正教历法有些细节不同,不是纯粹的格里历,只不过按照现行历法要到公元28世纪以后才能看得出区别。只是做万年历的话严格起见应该考虑到这点。
另外,和现行公历(格里历)兼容的历改方案有很多,比较简单的是加设3200/86400置闰/取消置闰周期。这点应该算是完善历算程序的可选内容。
像128年置润法什么的不兼容历算算法就算了。
Nokia上的那个农历十有八九是查表。一般还是建议查表实现,尽管这样基本不可能做到“万年”历,但就算不查表,按现有实用的模型精度撑死能达到5000年。

论坛徽章:
0
47 [报告]
发表于 2012-05-31 19:51 |只看该作者
仅实现了公历日期的; 小case;

做项目都要有农历才行。。。

论坛徽章:
0
48 [报告]
发表于 2012-05-31 21:30 |只看该作者
话说,真正的万年历不好做。公历有几个日期是很奇怪的。

论坛徽章:
0
49 [报告]
发表于 2012-06-01 11:10 |只看该作者
只是公历的星期,好像只要注意闰年就行了
农历的只能靠对照表了

论坛徽章:
5
金牛座
日期:2013-12-04 11:26:08处女座
日期:2013-12-04 12:32:17金牛座
日期:2014-03-19 09:49:11双鱼座
日期:2014-03-20 08:28:152015亚冠之柏斯波利斯
日期:2015-05-30 09:01:13
50 [报告]
发表于 2014-06-04 10:39 |只看该作者
lz不是用的蔡勒公式吗?
貌似蔡勒公式 要分1582年10月4日前后的吧 之前和之后 公式有差别
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP