万年历算法的实现
- 格式:doc
- 大小:94.00 KB
- 文档页数:18
用c语言编写万年历思路摘要:1.编写万年历的思路2.C 语言编程基础知识3.实现万年历的算法4.具体编程步骤5.总结正文:编写万年历的思路:万年历是一种能够显示任意一年中每个月的日期、星期和节假日的日历。
它可以方便人们在日程安排、计划活动时提供参考。
用C 语言编写万年历,需要运用C 语言编程基础知识和实现万年历的算法。
下面我们将详细介绍如何用C 语言编写万年历的思路和具体编程步骤。
C 语言编程基础知识:C 语言是一种广泛应用的编程语言,它具有语法简单、执行速度快等特点。
C 语言编程基础知识包括数据类型、运算符、控制结构、函数、数组、指针等。
对于初学者来说,掌握这些基础知识是编写万年历的前提。
实现万年历的算法:实现万年历的算法较为复杂,但可以分为以下几个步骤:1.判断闰年:判断一个年份是否为闰年的方法是:能被4 整除且不能被100 整除,或者能被400 整除。
闰年的二月有29 天,平年二月有28 天。
2.计算每个月的天数:根据月份和是否为闰年,计算每个月的天数。
其中,1、3、5、7、8、10、12 月为大月,每月31 天;4、6、9、11 月为小月,每月30 天。
3.计算星期数:根据给定的日期,计算该日期是星期几。
4.输出结果:根据计算得到的每个月的天数、星期数和节假日,输出万年历。
具体编程步骤:1.定义一个结构体,用于存储每个月的天数、星期数和节假日。
2.编写一个函数,用于判断一个年份是否为闰年。
3.编写一个函数,用于计算每个月的天数。
4.编写一个函数,用于计算给定日期是星期几。
5.编写一个函数,用于输出万年历。
6.在主函数中,调用上述函数,输入一个年份,输出该年份的万年历。
总结:用C 语言编写万年历,需要掌握C 语言编程基础知识和实现万年历的算法。
通过分析算法,我们可以将问题分解为若干个子问题,编写相应的函数来实现。
最后,在主函数中调用这些函数,完成万年历的输出。
用c语言编写万年历思路摘要:1.编写万年历的思路2.C 语言编程基础3.实现万年历的算法4.具体编写代码5.测试与优化正文:编写万年历的思路:万年历是一种能够显示任意一年中每月每日的日历,它可以方便地帮助人们查询日期和节日。
在C 语言中编写万年历需要运用一些基本的编程知识和算法。
本文将从编写万年历的思路、C 语言编程基础、实现万年历的算法、具体编写代码以及测试与优化等方面来介绍如何用C 语言编写万年历。
C 语言编程基础:在开始编写万年历之前,我们需要了解一些C 语言的基础知识,例如变量、循环、条件语句等。
C 语言是一种高级编程语言,它可以用来编写操作系统、编译器等各种应用程序。
C 语言具有语法简单、执行效率高的特点,因此在编写万年历时,我们可以选择使用C 语言来进行编程。
实现万年历的算法:万年历的实现需要运用一些基本的算法,例如计算平年和闰年的天数、计算每个月的天数等。
我们可以通过一个数组来存储每一年的天数信息,然后根据需要输出相应的日期。
在实现万年历的过程中,我们需要注意闰年的判断,根据闰年的规则,每4 年一闰,每100 年不闰,每400 年再闰。
具体编写代码:在具体编写代码时,我们需要按照一定的逻辑顺序进行编程。
首先,我们需要输入年份,然后根据年份计算出该年的天数信息。
接着,我们可以使用循环语句来逐月输出日期。
在输出日期时,我们需要注意每个月的天数,以及每个月的日期格式。
测试与优化:在编写完万年历程序后,我们需要对其进行测试和优化。
首先,我们可以通过输入一些年份来测试程序的正确性。
在测试过程中,我们需要注意程序的运行速度和正确性。
如果发现程序存在问题,我们需要及时进行优化和修改。
总之,用C 语言编写万年历需要掌握一定的编程基础和算法知识。
在编写程序时,我们需要注意代码的逻辑性和正确性,以便能够输出正确的日期信息。
Java实现简单的万年历本⽂实例为⼤家分享了Java实现简单万年历的具体代码,供⼤家参考,具体内容如下1 要求1、输⼊年份;2、输⼊⽉份;3、输出某年某⽉的⽇历。
2 思路1、实现从控制台接收年和⽉,判断是否是闰年(判断是否是闰年:能被4整除但不能被100整除;或者能被400整除);2、计算输⼊⽉份的天数;3、计算该⽉第⼀天是星期⼏;3.1 计算输⼊年份距离1900年1⽉1⽇的天数;3.2 计算输⼊⽉份之前的天数(从当年年初开始);3.3 将以上两组数据进⾏求和;3.4 已知该⽉之前的天数,计算输⼊⽉份的第⼀天是星期⼏(从1900年1⽉1⽇(星期⼀)开始推算: 星期⼏ = 1 + 天数差 % 7 )。
4、按格式输出该⽉⽇历。
3 源代码import java.util.Scanner;public class index {//每个⽉的天数public static int monthday(int month, int year) {if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {int[] day = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};return day[month];} else {int[] day = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};return day[month];}}//⽉份总天数public static int monthdays(int month, int year) {int totaldays = 0;for (int i = 1; i < month; i++) {totaldays = totaldays + monthday(i, year);}return totaldays;}//距离1900年的年份总天数public static int yeardays(int year){int yeardays = 0;for (int i = 1900;i<year;i++){if ((i % 4 == 0 && i % 100 != 0) || i % 400 == 0) {yeardays = yeardays+366;} else {yeardays = yeardays+365;}}System.out.println(year+"年距离1900年的总天数"+yeardays);return yeardays;}//输出⽇历public static void printCalendar(int month,int year){int totaldays = 0;if (year > 0) {if (month > 0 && month < 13) {//距离1900年1⽉1⽇总天数totaldays = monthdays(month,year)+yeardays(year);System.out.println(year+"年"+month+"⽉1⽇距离1900年的总天数:"+totaldays);System.out.println("\n**********"+year+"年"+month+"⽉的⽇历为**********");System.out.println("⼀\t⼆\t三\t四\t五\t六\t⽇\t");int week = 1+totaldays%7;//根据1⽇为周⼏输出空格for(int i=1;i<week;i++){System.out.print(" \t");}//输⼊具体⽇期for(int i=1;i<=monthday(month,year);i++){System.out.print(i+"\t");if(week==7){week = 1;//重置为星期⼀System.out.println();}else{week++;}}} else {System.out.println("输⼊的⽉份不合法!");}} else {System.out.println("输⼊的年份不合法!");}}//主函数public static void main(String[] args) {Scanner scanner = new Scanner(System.in);System.out.println("***********************欢迎使⽤万年历**************************");System.out.println("*********请选择你需要进⾏的操作(输⼊进⾏操作之前的数字)**********"); System.out.println("********************1.查询某年某⽉的⽇历************************");System.out.println("********************2.结束操作*********************************");System.out.print("\n请选择你需要进⾏的操作:");int a = scanner.nextInt();for (int i=0;i>=0;i++) {switch (a) {case 1:System.out.print("请选择年份:");int year = scanner.nextInt();System.out.print("请选择⽉份:");int month = scanner.nextInt();printCalendar(month, year);System.out.print("\n请选择你需要进⾏的操作:");a = scanner.nextInt();break;case 2:System.out.println("退出程序成功!");return;}}}}4 结果截图注意:我的周⽇是在最后⼀栏以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
万年历算命算法
万年历算命算法有种方法,只需记住十四字的歌诀,一年中的干支纪时就可迅速算出。
这种快速心算万年历的方法,叫银盘子。
银盘子是民间术士创造的万年历速算法,历史悠久,以往采用师徒间口授方法传授,严禁外传。
银盘子歌诀如下:
戊子青牛廿六临,
玉兰金狗子上寻。
瞎子算命就是靠背诵的“银盘子”的,也叫“盲历”。
银盘子是以农历为基础,推算干支纪时的方法。
农历有大月、小月之分,大月天,小月天。
如果不考虑小月因素,农历两个月天,与一个甲子六十组干支数目相符,即每两个月可重合一个甲子。
按照这样一个规律,了某年的正月初一的日干支,就等于了三月初一,五月初一,七月初一,九月初一,十一月初一的日干支,这几个月的初一的日干支,应是相同的有闰月者,月分稍有变化因为农历中存在小月,只要某年有几个小月,其分别为哪几个月,所推日期经历了几个小月,干支纪日顺延几天就是了,这样心算干支纪日就变得十分简单了。
银盘于还将十天干用五色来代表:
甲乙青丙丁红
戊巳黄庚辛白
壬癸黑。
心算万年历,必须了解以下四个要点:该年岁次;正月初一的日干支;立春的日、时;当年几个小月,分别为哪几个月。
银盘子仅用了十四个字的歌诀,便将以上四个问题地解决了。
银盘子的创造者,为了保守秘密,在编制口诀时,采用了加密术,即对同一地支,往往采用多种称谓。
这样做,一是提供了多一些的音韵,使编出的歌诀押韵。
而更主要的是为这种心算法采取了加密。
同一地支众多称谓,变换使用,即便外人听到也不得其解。
万年历的C语言编程实现源程序:#include<stdio.h>#include<stdlib.h>int Isleapyear(int y)/*判断是否是闰年*/{if((y%4==0&&y%100!=0)||(y%400==0))return 1;elsereturn 0;}int Getdaysofmonth(int y,int m)/*确定某个月的天数*/{int months[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};if(Isleapyear(y))/*如果是闰年则2月份的天数改变为29*/ months[2]=29;return months[m];}int Gettotaldays(int y,int m)/*计算从1901年1月开始到给定年月的天数*/{intmonths[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};int days=0;int i,j;if((Isleapyear(y)))months[2]=29;for(i=1901;i<y;i++)/*从1901年1月开始计算,累加y年之前的天数*/{if(Isleapyear(i))days+=366;elsedays+=365;}for(j=1;j<m;j++)/*累加m月之后的天数*/days+=months[j];return days;}int Getfirstdayintable(int y,int m)/*计算给定年月的第一天在日历表中的位置*/{int d;d=Gettotaldays(y,m);d=d+3;/*1901年1月1日是星期二,在日历中星期二是第三个位置*/d=d%7;return d;}void Showdate(int y,int m)/*显示日历*/{int first;int d;int i,k;first=Getfirstdayintable(y,m);/*得到第一天在日历中的第一个位置*/d=Getdaysofmonth(y,m);/*得到这个月的天数*/k=0;printf("-------------------------------------\n");printf(" SUN MON TUE WEN THU FRI STA\n");for(i=1;i<first;i++)/*打印第一天之前的空格*/{printf(" ");k++;/*k用于确定日历中是否回车*/}for(i=1;i<=d;i++){printf("%5d",i);/*每个具体的日期占5个字符的宽度*/k++;if(k==7)/*每行打印7个日期数字后回车*/{printf("\n");k=0;}}printf("\n-------------------------------------\n"); }int main(){int y,m;printf("Input year:");scanf("%d",&y);printf("Input month:");scanf("%d",&m);Showdate(y,m);return 0;}欢迎您的下载,资料仅供参考!致力为企业和个人提供合同协议,策划案计划书,学习资料等等打造全网一站式需求。
摘自: 星期、干支、二十八宿计算公式打印本页关闭本窗口1. 求星期公式星期=[5+A(实际天数)] mod 72. 干支计算公式六十甲子干支序号,从1->59->0。
六十甲子干支序号=[23+A(实际天数)] mod 603. 二十八宿计算公式二十八宿序号=[23+A(实际天数)] mod 284. 实际天数A的计算A=B(基本天数)+C(闰日天数)B=(计算年-1)*365+(要计算到年的月日天数)例:1984年2月1日的基本天数B=(1984-1)*365+(31+1)=723827(天),其中,31是1月为31天,1为2月1日为1天。
公元308年8月28日的基本天数B=(308-1)*365+(31+28+31+30+31+30+31+27)=112055+239=112294(天)这里的(要计算到年的月日天数),用的是公历,月日天数的规则我好象小学就学过了。
哈哈……C=(计算年-1) div 4 -误差修正值+ fixValue2fixValue2为0或者1。
常值为0,当年数为闰年(公历闰年法)之中的3月1日之后的为1。
误差修正值推算:公元元年1月1日至1582年10月14日为0。
1582年10月15日至1699年12月31日为10。
从1701年1月1日起每增加一个世纪累加1,但能被400除尽的世纪不累加1。
此方法推算即可。
--有一个问题,1700年这一年的修正值应为多少呢?算法中正好没有讲到,但看来应该是10。
例1701年1月1日起误差值为11,而1801年1月1日起误差修正值为12,而1901年1月1日起误差修正值为13,但2001年误差修正值仍为13,因为2000年能被400整除,故不累加。
而2101年1月1日起误差修正值为14。
5. 实例:1998.3.15的星期、干支与二十八宿B=(1998-1)*365+(31+28+15)=728979C=(1998-1) div 4 - 13 + 0 = 486A=B+C=728979+486=729465星期序号=(5+729465) mod 7=0,即为星期日干支序号=(13+729465) mod 60=58,即为辛酉二十八宿序号=(23+729465) mod 28=4,即为房===================================================好可怕!还有一些其它公式……但好象有些参数不知道怎么得到:二十四节交节日算法:用已知年的交接时辰加上22个小时35分,超过24要减去24,分数足60 进1个小时,即得到8年后的各节交节时辰。
万年历计算方法1。
平年365天(52周+1天),闰年366天(52周+2天)。
平年2月28天,闰年2月29天。
由于公元1月1日设为星期六,故3月1日为星期三。
——注意这个“三”为使算法达到最简,故本算法以“星期”为计算单位。
且选3月1日为基月。
2。
每400年整一闰,或每4年且不为百年的一闰。
(原因:地球绕太阳一周的时间是365天5小时46秒,为了使一年的天数为整数,将一年的天数定为365天,余下的时间积累起来,四年就是23小时15分4秒,将近一天,把这一天加在某年的二月而成29天,该年称为闰年,其它年称为平年。
但四年加一天又多用了44分56秒,这个数积满400年为三天。
因此400年中只能有97个闰年,所以凡能被400整除,或不能被100整除但能被4整除的年份为闰年。
)所以百年%4=0闰或(年%4=0并且年<>0)闰。
3。
每 4年(3个平年+1个闰年)共208周+5天——注意这个“5天”每百年共100*(208周+5天)-1天=5217周+5天——注意这个“5天”(整百年暂设为平年)每400年共4*(5217周+5天)+1天(整400年闰)=20871周+0天——注意这个“0天”和“1天”(4个整百年只有一个闰年)即400年一轮回!(原来万年历400年前是一家)蔡勒(Zeller)公式历史上的某一天是星期几?未来的某一天是星期几?关于这个问题,有很多计算公式(两个通用计算公式和一些分段计算公式),其中最著名的蔡勒(Zeller)公式即w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1公式中的符号含义如下,w:星期;c:世纪-1;y:年(两位数);m:月(m大于等于3,小于等于14,即在蔡勒公式中,某年的1、2月要看作上一年的13、14月来计算,比如2003年1月1日要看作2002年的13月1日来计算);d:日;[ ]代表取整,即只要整数部分。
(C是世纪数减一,y是年份后两位,M是月份,d是日数。
万年历原理
万年历是一种用来记录和显示日期的工具,它可以帮助人们方便地查看某一年、某一月或某一日的具体日期信息。
万年历的原理是基于公历的规律和历法计算。
公历是目前世界上最普遍使用的阳历,它采用太阳年和太阳日来计算时间。
太阳年的长度约为365.2425天,太阳日则是地
球绕太阳一周所需的时间。
然而,公历中规定的一年只有365天,为了弥补年与日之间的差距,每4年中会多出一个闰日,这一年就是闰年。
具体闰年的计算方法为:能被4整除但不能被100整除,或者能被400整除的年份都是闰年。
万年历的原理就是根据公历的规则计算某一天、某一月的具体日期,并配以星期的显示。
其中,星期的计算需要通过已知的起始日期和当天的天数差来确定,通常采用桥年法或詹森公式。
除了公历的基本原理,万年历还需要考虑其他因素,如月份的天数和每个月的起始日等。
一种广泛使用的万年历算法是蔡勒公式,它可以计算任意日期的星期、月份和日期。
根据这个算法,我们可以确定某一天是星期几,从而将日期显示在万年历上。
总之,万年历的原理是基于公历的规律和历法计算,它能够准确地显示任意日期的具体信息,帮助人们更方便地管理时间和安排日程。
万年历工作原理
万年历是一种用来显示日期和周历的工具。
它的工作原理主要基于以下几个方面:
1. 年份计算:万年历首先需要通过一个算法来计算年份。
这个算法通常会考虑闰年的规律,以确定每一年是平年还是闰年。
根据阳历的计算方式,闰年一般为能够被4整除但不能被100
整除的年份,或者能够被400整除的年份。
2. 日期显示:万年历会通过一个日期显示系统,将当年的每一天以适当的格式呈现出来。
日期显示系统通常会将每个月的日期按照适当的行列进行排列,以方便用户查看。
3. 周日历显示:除了日期显示外,万年历还需要显示每周的日历。
这可以通过计算每个月的第一天是星期几,并据此确定每周的排列顺序来实现。
4. 补偿:由于历法的复杂性,万年历通常会考虑一些特殊情况,例如历法改革或历法规则的变化。
在这种情况下,万年历需要进行一些补偿或调整,以确保日期的准确性。
综上所述,万年历的工作原理主要包括年份的计算、日期的显示、周日历的显示以及一些特殊情况的补偿。
通过这些工作步骤,万年历可以准确地显示出任意年份的日期和周日历。
C语言实现万年历摘要:介绍使用C语言实现万年历的打印与输出。
关键字:C;万年历;打印与输出一引言万年历是我们日常生活中经常用到的一种非常实用的工具。
由于工作繁忙,人们常常忘记某一天是星期几,或者想快速地查询某一年中某一天是星期几,这里万年历就能派上用场了。
本文将介绍一种万年历的实现方法,通过C语言编程实现基本的万年历查询功能,读者可以在本文的基础上开发出更具个性化的万年历来。
二设计思想由于万年历具有以下特点:1 平年365天(52周+1天),闰年366天(52周+2天),平年2月28天,闰年2月29天。
由于公元1月1日设为星期六,故3月1日为星期三。
为使算法达到最简,故本算法以“星期”为计算单位,且选3月1日为基月。
2 每400年整一闰,或每4年且不为百年的一闰,即凡能被400整除,或不能被100整除但能被4整除的年份为闰年。
3 每 4年(3个平年+1个闰年)共208周+5天每百年共100*(208周+5天)-1天=5217周+5天每400年共4*(5217周+5天)+1天(整400年闰)=20871周+0天,即每400年一个轮回。
三万年历实现的方法1 程序预处理程序预处理包括头文件加载、宏定义和全局变量的定义。
#include"stdio.h"#include"dos.h"#include"conio.h"#include"stdlib.h"#define LeapYear (x) (x%4==0&&x%100!=0||x%400==0)?1:0struct date sysTime;2 功能控制模块功能控制模块包括每月天数判定功能、每年天数判定功能、星期计算功能。
分别由函数Monthnum()、Yearnum()、IsWeek()和*getWeek()(1)int Monthnum(int y,int m),判定每月天数。
万年历的工作原理
万年历的工作原理基于格里历(即阳历)和儒略历(即农历)两种历法的组合运算。
它通过计算年、月、日、星期等信息来构建一个长期连续的历法系统。
其主要包括以下几个方面的运算:
1. 判断闰年:根据格里历的规则,每4年有一个闰年,但是整百年不闰,四百年再闰。
通过判断年份是否符合这个规则,可以确定某一年是否为闰年。
2. 计算星期几:基于格里历的规则,可以通过某一年、某一月、某一日来计算出当天是星期几。
这个计算方法利用了一个已知的基准日期,比如万年历中常用的是1582年10月4日是星期一,根据与此基准日期相差的天数进行计算。
3. 农历转换:万年历中还包含了农历的信息。
农历的月份是根据农历规则计算的,每个月的天数和月份的名称都不固定,需要通过一系列复杂的历法运算来进行确定。
这样,可以通过输入一个阳历日期,计算出对应的农历日期。
4. 显示月历:根据以上计算结果,可以显示出某一年、某一月的月历,包括阳历和农历的日期信息。
在显示时,一般会标记出公历的重要节日和农历的重要节日,以方便用户查看。
万年历的工作原理就是基于这些计算方法,将格里历和农历的
信息结合起来,提供一个长期连续的历法系统,方便人们查询日期信息。
万年历程序简介万年历(Perpetual Calendar)是一个可以显示公历和农历的时间工具。
在这个文档中,我们将讨论如何编写一个简单的万年历程序,以及其实现原理和功能。
功能该万年历程序将具备以下功能:1.显示当前日期2.显示当前周数3.显示当前月份的日历4.显示指定年份和月份的日历实现原理为了实现万年历程序,我们需要使用一些基本的计算方法。
以下是一些相关的计算原理:判断某年是否是闰年判断某年是否是闰年可以使用以下公式:is_leap_year = (year % 4 == 0 and year % 100 ! = 0) or (year % 400 == 0)若上述公式的值为真,则表示该年份是闰年。
计算指定年份和月份的天数可以使用以下公式来计算指定年份和月份的天数:days_in_month = [31, # 1月28 + is_leap_year, # 2月31, # 3月30, # 4月31, # 5月30, # 6月31, # 7月31, # 8月30, # 9月31, # 10月30, # 11月31 # 12月]这样,我们就可以得到每个月份的天数。
判断某年某月的第一天是星期几我们可以使用Zeller’s Congruence算法来判断某年某月的第一天是星期几。
以下是该算法的公式:h = (day + 26*(month+1)//10 + k + k//4 + j//4 + 5*j) % 7其中,h是星期几(0代表星期六,1代表星期日,依次类推),day是月份的第一天的日期,month是月份(3代表三月,4代表四月,依次类推),k是该年的前两位数,j是该年的后两位数。
实现步骤以下是实现万年历程序的步骤:1.获取当前日期和时间2.使用相关公式判断当前年份是否是闰年3.显示当前日期和时间4.计算当前周数并显示5.获取当前月份的相关信息:年份、月份、天数、星期几6.显示当前月份的日历7.提供用户界面,允许用户输入指定的年份和月份8.使用相关算法计算指定年份和月份的日历9.显示指定年份和月份的日历示例代码以下是使用Python语言实现的一个简单的万年历程序:```python import datetime获取当前日期today = datetime.date.today() current_year = today.year current_month = today.month current_day = today.day判断当前年份是否是闰年is_leap_year = (current_year % 4 == 0 and current_year % 100 != 0) or (current_year % 400 == 0)显示当前日期和时间print(。
万年历---java算法实现万年历是我在网上见到的一份极高高精度的万年历,其采用先进的算法实现,其精度堪比刘安国教授为中国科学院国家授时中心制作的日梭万年历。
但网络上只有javascript 版本。
于是自己将其翻译为java程序,并公布于此,方便大家使用。
本文中讲的万年历是一款采用现代天文算法制作的农历历算程序,含有公历与回历信息,可以很方便的进行公、农、回三历之间的转换。
提供公元-4712年到公元9999年的日期查询功能。
其中1500年到1940农历数据已经与陈垣的《二十史朔闰表》核对;含有从公420元(南北朝/宋武帝元年)到今的基本年号。
在过去几百年中,寿星万年历的误差是非常小的,节气时刻计算及日月合朔时刻的平均误差小于1秒,太阳坐标的最大可能误差为0.2角秒,月亮坐标的最大可能误差为3角秒,平均误差为误差的1/6。
万年历中含有几百个国内城市的经纬度,并且用户可根据自已的需要扩展经纬度数据。
代码如下:/*** @author lxslove* @mail moodlxs at 163**/public class SolarTerm {// ========角度变换===============private static final double rad = 180 * 3600 / Math.PI; // 每弧度的角秒数private static final double RAD = 180 / Math.PI; // 每弧度的角度数// ================日历计算===============private static final double J2000 = 2451545; // 2000年前儒略日数(2000-1-1// 12:00:00格林威治平时)// =========黄赤交角及黄赤坐标变换===========private static final double hcjjB[] = { 84381.448, -46.8150, -0.00059,0.001813 };// 黄赤交角系数表private static final double preceB[] = { 0, 50287.92262, 111.24406,0.07699, -0.23479, -0.00178, 0.00018, 0.00001 };// Date黄道上的岁差pprivate double Y = 2000;private double M = 1;private double D = 1;private double h = 12;private double m = 0;private double s = 0;private static final double[] dts = {// 世界时与原子时之差计算表-4000, 108371.7, -13036.80, 392.000, 0.0000, -500, 17201.0,-627.82, 16.170, -0.3413, -150, 12200.6, -346.41, 5.403, -0.1593, 150, 9113.8, -328.13, -1.647, 0.0377, 500, 5707.5, -391.41, 0.915, 0.3145, 900, 2203.4, -283.45, 13.034, -0.1778, 1300, 490.1, -57.35, 2.085, -0.0072, 1600, 120.0, -9.81, -1.532, 0.1403, 1700, 10.2,-0.91, 0.510, -0.0370, 1800, 13.4, -0.72, 0.202, -0.0193, 1830,7.8, -1.81, 0.416, -0.0247, 1860, 8.3, -0.13, -0.406, 0.0292, 1880, -5.4, 0.32, -0.183, 0.0173, 1900, -2.3, 2.06, 0.169, -0.0135, 1920, 21.2, 1.69, -0.304, 0.0167, 1940, 24.2, 1.22, -0.064, 0.0031, 1960, 33.2, 0.51, 0.231, -0.0109, 1980, 51.0, 1.29, -0.026, 0.0032, 2000, 64.7, -1.66, 5.224, -0.2905, 2150, 279.4, 732.95, 429.579, 0.0158, 6000 };// 取整数部分public static double int2(double v) {v = Math.floor(v);if (v < 0)return v + 1;return v;}// 对超过0-2PI的角度转为0-2PIpublic static double rad2mrad(double v) {v = v % (2 * Math.PI);if (v < 0)return v + 2 * Math.PI;return v;}// 计算世界时与原子时之差,传入年public double deltatT(double y) {int i = 0;for (i = 0; i < 100; i += 5)if (y < dts[i + 5] || i == 95)break;double t1 = (y - dts[i]) / (dts[i + 5] - dts[i]) * 10;double t2 = t1 * t1;double t3 = t2 * t1;return dts[i + 1] + dts[i + 2] * t1 + dts[i + 3] * t2 + dts[i + 4] * t3;}// 传入儒略日(J2000起算),计算UTC与原子时的差(单位:日)public double deltatT2(double jd) {return this.deltatT(jd / 365.2425 + 2000) / 86400.0;}// 公历转儒略日,UTC=1表示原日期是UTCpublic double toJD(boolean UTC) {double y = this.Y; // 取出年月double m = this.M;double n = 0;if (m <= 2) {m += 12;y--;}if (this.Y * 372 + this.M * 31 + this.D >= 588829) {// 判断是否为格里高利历日1582*372+10*31+15n = int2(y / 100);n = 2 - n + int2(n / 4);// 加百年闰}n += int2(365.2500001 * (y + 4716)); // 加上年引起的偏移日数n += int2(30.6 * (m + 1)) + this.D; // 加上月引起的偏移日数及日偏移数 n += ((this.s / 60 + this.m) / 60 + this.h) / 24 - 1524.5;if (UTC)return n + this.deltatT2(n - J2000);}// 儒略日数转公历,UTC=1表示目标公历是UTCpublic void setFromJD(double jd, boolean UTC) {if (UTC)jd -= this.deltatT2(jd - J2000);jd += 0.5;// 取得日数的整数部份A及小数部分Fdouble A = int2(jd);double F = jd - A;double D;if (A > 2299161) {D = int2((A - 1867216.25) / 36524.25);A += 1 + D - int2(D / 4);}A += 1524; // 向前移4年零2个月this.Y = int2((A - 122.1) / 365.25);// 年D = A - int2(365.25 * this.Y); // 去除整年日数后余下日数this.M = int2(D / 30.6001); // 月数this.D = D - int2(this.M * 30.6001);// 去除整月日数后余下日数 this.Y -= 4716;this.M--;if (this.M > 12)this.M -= 12;if (this.M <= 2)this.Y++;// 日的小数转为时分秒F *= 24;this.h = int2(F);F -= this.h;F *= 60;this.m = int2(F);F -= this.m;F *= 60;}// 设置时间,参数例:"20000101 120000"或"20000101"public void setFromStr(String s) {this.Y = Double.parseDouble(s.substring(0, 4));this.M = Double.parseDouble(s.substring(4, 2));this.D = Double.parseDouble(s.substring(6, 2));this.h = Double.parseDouble(s.substring(9, 2));this.m = Double.parseDouble(s.substring(11, 2));this.s = Double.parseDouble(s.substring(13, 2)); /* 将5改为了2 */ }// 日期转为串public String toStr() {String Y = " " + (int)this.Y;String M = "0" + (int)this.M;String D = "0" + (int)this.D;double h = this.h, m = this.m, s = Math.floor(this.s + .5);if (s >= 60) {s -= 60;m++;}if (m >= 60) {m -= 60;h++;}String sh = "0" + (int)h, sm = "0" + (int)m, ss = "0" + (int)s;Y = Y.substring(Y.length() - 5, Y.length());M = M.substring(M.length() - 2, M.length());D = D.substring(D.length() - 2, D.length());sh = sh.substring(sh.length() - 2, sh.length());sm = sm.substring(sm.length() - 2, sm.length());ss = ss.substring(ss.length() - 2, ss.length());return Y + "-" + M + "-" + D + " " + sh + ":" + sm + ":" + ss;}// 算出:jd转到当地UTC后,UTC日数的整数部分或小数部分// 基于J2000力学时jd的起算点是12:00:00时,所以跳日时刻发生在12:00:00,这与日历计算发生矛盾// 把jd改正为00:00:00起算,这样儒略日的跳日动作就与日期的跳日同步// 改正方法为jd=jd+0.5-deltatT+shiqu/24// 把儒略日的起点移动-0.5(即前移12小时)// 式中shiqu是时区,北京的起算点是-8小时,shiqu取8public double Dint_dec(double jd, int shiqu, boolean dec) {double u = jd + 0.5 - this.deltatT2(jd) + shiqu / 24;if (dec)return Math.floor(u); // 返回整数部分elsereturn u - Math.floor(u); // 返回小数部分}// 计算两个日期的相差的天数,输入字串格式日期,如:"20080101"double d1_d2(String d1, String d2) {double Y = this.Y, M = this.M, D = this.D, h = this.h, m = this.m, s = this.s; // 备份原来的数据this.setFromStr(d1.substring(0, 8) + " 120000");double jd1 = this.toJD(false);this.setFromStr(d2.substring(0, 8) + " 120000");double jd2 = this.toJD(false);this.Y = Y;this.M = M;this.D = D;this.h = h;this.m = m;this.s = s; // 还原if (jd1 > jd2)return Math.floor(jd1 - jd2 + .0001);elsereturn -Math.floor(jd2 - jd1 + .0001);}// 返回黄赤交角(常规精度),短期精度很高public static double hcjj1(double t) {double t1 = t / 36525;double t2 = t1 * t1;double t3 = t2 * t1;return (hcjjB[0] + hcjjB[1] * t1 + hcjjB[2] * t2 + hcjjB[3] * t3) / rad;}// 黄赤转换(黄赤坐标旋转)public static void HCconv(double[] JW, double E) {// 黄道赤道坐标变换,赤到黄E取负double HJ = rad2mrad(JW[0]), HW = JW[1];double sinE = Math.sin(E), cosE = Math.cos(E);double sinW = cosE * Math.sin(HW) + sinE * Math.cos(HW) * Math.sin(HJ); double J = Math.atan2(Math.sin(HJ) * cosE - Math.tan(HW) * sinE, Math.cos(HJ));JW[0] = rad2mrad(J);JW[1] = Math.asin(sinW);}// 补岁差public static void addPrece(double jd, double[] zb) {int i;double t = 1, v = 0, t1 = jd / 365250;for (i = 1; i < 8; i++) {t *= t1;v += preceB[i] * t;}zb[0] = rad2mrad(zb[0] + (v + 2.9965 * t1) / rad);}// ===============光行差==================private static final double GXC_e[] = { 0.016708634, -0.000042037,-0.0000001267 }; // 离心率private static final double GXC_p[] = { 102.93735 / RAD, 1.71946 / RAD,0.00046 / RAD }; // 近点private static final double GXC_l[] = { 280.4664567 / RAD,36000.76982779 / RAD, 0.0003032028 / RAD, 1 / 49931000 / RAD,-1 / 153000000 / RAD }; // 太平黄经private static final double GXC_k = 20.49552 / rad; // 光行差常数// 恒星周年光行差计算(黄道坐标中)public static void addGxc(double t, double[] zb) {double t1 = t / 36525;double t2 = t1 * t1;double t3 = t2 * t1;double t4 = t3 * t1;double L = GXC_l[0] + GXC_l[1] * t1 + GXC_l[2] * t2 + GXC_l[3] * t3+ GXC_l[4] * t4;double p = GXC_p[0] + GXC_p[1] * t1 + GXC_p[2] * t2;double e = GXC_e[0] + GXC_e[1] * t1 + GXC_e[2] * t2;double dL = L - zb[0], dP = p - zb[0];zb[0] -= GXC_k * (Math.cos(dL) - e * Math.cos(dP)) / Math.cos(zb[1]);zb[1] -= GXC_k * Math.sin(zb[1]) * (Math.sin(dL) - e * Math.sin(dP));zb[0] = rad2mrad(zb[0]);}// ===============章动计算==================private static final double nutB[] = {// 章动表2.1824391966, -33.757045954, 0.0000362262, 3.7340E-08, -2.8793E-10, -171996, -1742, 92025, 89, 3.5069406862, 1256.663930738,0.0000105845, 6.9813E-10, -2.2815E-10, -13187, -16, 5736, -31,1.3375032491, 16799.418221925, -0.0000511866, 6.4626E-08,-5.3543E-10, -2274, -2, 977, -5, 4.3648783932, -67.514091907,0.0000724525, 7.4681E-08, -5.7586E-10, 2062, 2, -895, 5,0.0431251803, -628.301955171, 0.0000026820, 6.5935E-10, 5.5705E-11, -1426, 34, 54, -1, 2.3555557435, 8328.691425719, 0.0001545547,2.5033E-07, -1.1863E-09, 712, 1, -7, 0,3.4638155059,1884.965885909, 0.0000079025, 3.8785E-11, -2.8386E-10, -517, 12,224, -6, 5.4382493597, 16833.175267879, -0.0000874129, 2.7285E-08, -2.4750E-10, -386, -4, 200, 0, 3.6930589926, 25128.109647645,0.0001033681, 3.1496E-07, -1.7218E-09, -301, 0, 129, -1,3.5500658664, 628.361975567, 0.0000132664, 1.3575E-09, -1.7245E-10, 217, -5, -95, 3 };public static class ZD {public double Lon;public double Obl;}// 计算黄经章动及交角章动public static ZD nutation(double t) {ZD d = new ZD();d.Lon = 0;d.Obl = 0;t /= 36525;double c, t1 = t, t2 = t1 * t1, t3 = t2 * t1, t4 = t3 * t1;// t5=t4*t1;for (int i = 0; i < nutB.length; i += 9) {c = nutB[i] + nutB[i + 1] * t1 + nutB[i + 2] * t2 + nutB[i + 3]* t3 + nutB[i + 4] * t4;d.Lon += (nutB[i + 5] + nutB[i + 6] * t / 10) * Math.sin(c); // 黄经章动d.Obl += (nutB[i + 7] + nutB[i + 8] * t / 10) * Math.cos(c); // 交角章动}d.Lon /= rad * 10000; // 黄经章动d.Obl /= rad * 10000; // 交角章动return d;}// 本函数计算赤经章动及赤纬章动public static void nutationRaDec(double t, double[] zb) {double Ra = zb[0], Dec = zb[1];double E = hcjj1(t), sinE = Math.sin(E), cosE = Math.cos(E); // 计算黄赤交角 ZD d = nutation(t); // 计算黄经章动及交角章动double cosRa = Math.cos(Ra), sinRa = Math.sin(Ra);double tanDec = Math.tan(Dec);zb[0] += (cosE + sinE * sinRa * tanDec) * d.Lon - cosRa * tanDec* d.Obl; // 赤经章动zb[1] += sinE * cosRa * d.Lon + sinRa * d.Obl; // 赤纬章动zb[0] = rad2mrad(zb[0]);}//=================以下是月球及地球运动参数表=================== /**************************************** 如果用记事本查看此代码,请在"格式"菜单中去除"自动换行"* E10是关于地球的,格式如下:* 它是一个数组,每3个数看作一条记录,每条记录的3个数记为A,B,C* rec=A*cos(B+C*t); 式中t是J2000起算的儒略千年数* 每条记录的计算结果(即rec)取和即得地球的日心黄经的周期量L0* E11格式如下: rec = A*cos*(B+C*t) *t, 取和后得泊松量L1* E12格式如下: rec = A*cos*(B+C*t) *t*t, 取和后得泊松量L2* E13格式如下: rec = A*cos*(B+C*t) *t*t*t, 取和后得泊松量L3* 最后地球的地心黄经:L = L0+L1+L2+L3+...* E20,E21,E22,E23...用于计算黄纬* M10,M11等是关于月球的,参数的用法请阅读Mnn()函数*****************************************///地球运动VSOP87参数private static final double E10[] = { //黄经周期项1.75347045673, 0.00000000000, 0.0000000000, 0.03341656456,4.66925680417, 6283.0758499914, 0.00034894275, 4.62610241759,12566.1516999828, 0.00003417571, 2.82886579606, 3.5231183490,0.00003497056, 2.74411800971, 5753.3848848968, 0.00003135896, 3.62767041758, 77713.7714681205, 0.00002676218,4.41808351397, 7860.4193924392, 0.00002342687,6.135********, 3930.2096962196,0.00001273166, 2.0370*******, 529.6909650946, 0.00001324292, 0.74246356352, 11506.7697697936, 0.00000901855,2.0450*******, 26.2983197998, 0.00001199167, 1.10962944315, 1577.3435424478,0.00000857223, 3.50849156957, 398.1490034082, 0.00000779786,1.178********, 5223.6939198022, 0.00000990250,5.23268129594, 5884.9268465832, 0.00000753141,2.53339053818, 5507.5532386674,0.00000505264, 4.58292563052, 18849.2275499742, 0.00000492379,4.20506639861, 775.5226113240, 0.00000356655,2.91954116867, 0.0673103028, 0.00000284125, 1.89869034186, 796.2980068164, 0.00000242810, 0.34481140906, 5486.7778431750, 0.00000317087, 5.84901952218, 11790.6290886588, 0.00000271039, 0.31488607649,10977.0788046990, 0.00000206160, 4.80646606059, 2544.3144198834,0.00000205385, 1.86947813692, 5573.1428014331, 0.00000202261,2.45767795458, 6069.7767545534, 0.00000126184,1.0830*******, 20.7753954924, 0.00000155516, 0.83306073807, 213.2990954380, 0.00000115132, 0.64544911683, 0.9803210682, 0.00000102851,0.63599846727, 4694.0029547076, 0.00000101724,4.26679821365, 7.1135470008, 0.00000099206, 6.20992940258, 2146.1654164752, 0.00000132212, 3.41118275555, 2942.4634232916, 0.00000097607,0.68101272270, 155.4203994342, 0.00000085128,1.29870743025, 6275.9623029906, 0.00000074651,1.75508916159, 5088.6288397668,0.00000101895, 0.97569221824, 15720.8387848784, 0.00000084711,3.67080093025, 71430.6956181291, 0.00000073547,4.67926565481, 801.8209311238, 0.00000073874,3.50319443167, 3154.6870848956,0.00000078756, 3.03698313141, 12036.4607348882, 0.00000079637,1.80791330700, 17260.1546546904, 0.00000085803,5.98322631256,161000.6857376741, 0.00000056963,2.78430398043, 6286.5989683404,0.00000061148, 1.81839811024, 7084.8967811152, 0.00000069627,0.83297596966, 9437.7629348870, 0.00000056116, 4.38694880779,14143.4952424306, 0.00000062449, 3.97763880587, 8827.3902698748,0.00000051145, 0.28306864501, 5856.4776591154, 0.00000055577,3.47006009062, 6279.5527316424, 0.00000041036,5.36817351402, 8429.2412664666, 0.00000051605,1.33282746983, 1748.0164130670,0.00000051992, 0.189********, 12139.5535091068, 0.00000049000,0.48735065033, 1194.4470102246, 0.00000039200, 6.16832995016,10447.3878396044, 0.00000035566, 1.77597314691, 6812.7668150860,0.00000036770, 6.0413*******, 10213.2855462110, 0.00000036596,2.56955238628, 1059.3819301892, 0.00000033291, 0.59309499459,17789.8456197850, 0.00000035954, 1.70876111898, 2352.8661537718};private static final double E11[] = { //黄经泊松1项6283.31966747491,0.00000000000, 0.0000000000, 0.00206058863,2.67823455584, 6283.0758499914, 0.00004303430, 2.63512650414,12566.1516999828, 0.00000425264, 1.59046980729, 3.5231183490,0.00000108977, 2.96618001993, 1577.3435424478, 0.00000093478, 2.59212835365,18849.2275499742, 0.00000119261,5.79557487799, 26.2983197998, 0.00000072122, 1.138********, 529.6909650946, 0.00000067768, 1.87472304791, 398.1490034082, 0.00000067327,4.40918235168, 5507.5532386674, 0.00000059027,2.88797038460, 5223.6939198022, 0.00000055976,2.17471680261, 155.4203994342,0.00000045407, 0.39803079805, 796.2980068164, 0.00000036369,0.46624739835, 775.5226113240, 0.00000028958,2.64707383882, 7.1135470008, 0.00000019097, 1.84628332577, 5486.7778431750, 0.00000020844, 5.34138275149, 0.9803210682, 0.00000018508,4.96855124577, 213.2990954380, 0.00000016233,0.03216483047, 2544.3144198834, 0.00000017293,2.99116864949, 6275.9623029906};private static final double E12[] = { //黄经泊松2项0.00052918870, 0.00000000000, 0.0000000000, 0.00008719837,1.07209665242, 6283.0758499914, 0.00000309125, 0.86728818832,12566.1516999828, 0.00000027339, 0.05297871691, 3.5231183490,0.00000016334, 5.188********, 26.2983197998, 0.00000015752,3.68457889430, 155.4203994342, 0.00000009541, 0.75742297675,18849.2275499742, 0.00000008937, 2.0570*******, 77713.7714681205,0.00000006952, 0.82673305410, 775.5226113240, 0.00000005064,4.66284525271, 1577.3435424478};private static final double E13[] = { 0.00000289226,5.84384198723, 6283.0758499914, 0.00000034955, 0.00000000000, 0.0000000000, 0.00000016819, 5.48766912348, 12566.1516999828};private static final double E14[] = { 0.00000114084,3.14159265359, 0.0000000000, 0.00000007717,4.134********, 6283.0758499914, 0.00000000765, 3.83803776214, 12566.1516999828};private static final double E15[] = { 0.00000000878, 3.14159265359, 0.0000000000 }; private static final double E20[] = { //黄纬周期项0.00000279620, 3.198********, 84334.6615813083, 0.00000101643,5.42248619256, 5507.5532386674, 0.00000080445,3.88013204458, 5223.6939198022, 0.00000043806,3.70444689758, 2352.8661537718,0.00000031933, 4.00026369781, 1577.3435424478, 0.00000022724,3.98473831560, 1047.7473117547, 0.00000016392,3.56456119782, 5856.4776591154, 0.00000018141,4.98367470263, 6283.0758499914,0.00000014443, 3.70275614914, 9437.7629348870, 0.00000014304, 3.41117857525, 10213.2855462110};private static final double E21[] = { 0.00000009030,3.89729061890, 5507.5532386674, 0.00000006177,1.73038850355, 5223.6939198022};private static final double E30[] = { //距离周期项1.00013988799, 0.00000000000, 0.0000000000, 0.01670699626,3.09846350771, 6283.0758499914, 0.00013956023, 3.0552*******,12566.1516999828, 0.00003083720, 5.198********, 77713.7714681205,0.00001628461, 1.173********, 5753.3848848968, 0.00001575568,2.84685245825, 7860.4193924392, 0.00000924799, 5.45292234084,11506.7697697936, 0.00000542444, 4.56409149777, 3930.2096962196};private static final double E31[] = { 0.00103018608,1.10748969588, 6283.0758499914, 0.00001721238, 1.06442301418,12566.1516999828, 0.00000702215, 3.14159265359, 0.0000000000};private static final double E32[] = { 0.00004359385,5.78455133738, 6283.0758499914 };private static final double E33[] = { 0.00000144595,4.27319435148, 6283.0758499914 };//月球运动参数private static final double M10[] = {22639.5858800, 2.3555545723, 8328.6914247251, 1.5231275E-04, 2.5041111E-07,-1.1863391E-09, 4586.4383203, 8.0413790709, 7214.0628654588,-2.1850087E-04,-1.8646419E-07, 8.7760973E-10, 2369.9139357, 10.3969336431, 15542.7542901840,-6.6188121E-05, 6.3946925E-08,-3.0872935E-10, 769.0257187,4.7111091445, 16657.3828494503, 3.0462550E-04,5.0082223E-07,-2.3726782E-09,-666.4175399, -0.0431256817, 628.3019552485,-2.6638815E-06, 6.1639211E-10,-5.4439728E-11, -411.5957339, 3.2558104895, 16866.9323152810,-1.2804259E-04,-9.8998954E-09, 4.0433461E-11, 211.6555524, 5.6858244986, -1114.6285592663,-3.7081362E-04,-4.3687530E-07, 2.0639488E-09, 205.4359530, 8.0845047526, 6585.7609102104,-2.1583699E-04,-1.8708058E-07, 9.3204945E-10,191.9561973, 12.7524882154, 23871.4457149091, 8.6124629E-05, 3.1435804E-07,-1.4950684E-09, 164.7286185, 10.4400593249, 14914.4523349355,-6.3524240E-05, 6.3330532E-08,-2.5428962E-10, -147.3213842, -2.3986802540, -7700.3894694766,-1.5497663E-04,-2.4979472E-07, 1.1318993E-09, -124.9881185, 5.1984668216, 7771.3771450920,-3.3094061E-05, 3.1973462E-08,-1.5436468E-10,-109.3803637, 2.3124288905, 8956.9933799736, 1.4964887E-04, 2.5102751E-07,-1.2407788E-09, 55.1770578, 7.1411231536, -1324.1780250970, 6.1854469E-05, 7.3846820E-08,-3.4916281E-10, -45.0996092, 5.6113650618, 25195.6237400061, 2.4270161E-05, 2.4051122E-07,-1.1459056E-09, 39.5333010, -0.9002559173, -8538.2408905558, 2.8035534E-04, 2.6031101E-07,-1.2267725E-09,38.4298346, 18.4383127140, 22756.8171556428,-2.8468899E-04,-1.2251727E-07, 5.6888037E-10, 36.1238141, 7.0666637168, 24986.0742741754, 4.5693825E-04, 7.5123334E-07,-3.5590172E-09, 30.7725751, 16.0827581417, 14428.1257309177,-4.3700174E-04,-3.7292838E-07, 1.7552195E-09, -28.3971008, 7.9982533891, 7842.3648207073,-2.2116475E-04,-1.8584780E-07,8.2317000E-10,-24.3582283, 10.3538079614, 16171.0562454324,-6.8852003E-05, 6.4563317E-08,-3.6316908E-10, -18.5847068, 2.8429122493, -557.3142796331,-1.8540681E-04,-2.1843765E-07, 1.0319744E-09, 17.9544674, 5.1553411398, 8399.6791003405,-3.5757942E-05, 3.2589854E-08,-2.0880440E-10, 14.5302779, 12.7956138971, 23243.1437596606, 8.8788511E-05, 3.1374165E-07,-1.4406287E-09,14.3796974, 15.1080427876, 32200.1371396342, 2.3843738E-04, 5.6476915E-07,-2.6814075E-09, 14.2514576,-24.0810366320, -2.3011998397, 1.5231275E-04,2.5041111E-07,-1.1863391E-09, 13.8990596, 20.7938672862, 31085.5085803679,-1.3237624E-04, 1.2789385E-07,-6.1745870E-10, 13.1940636, 3.3302699264, -9443.3199839914,-5.2312637E-04,-6.8728642E-07, 3.2502879E-09,-9.6790568, -4.7542348263,-16029.0808942018,-3.0728938E-04,-5.0020584E-07, 2.3182384E-09, -9.3658635, 11.2971895604, 24080.9951807398,-3.4654346E-04,-1.9636409E-07, 9.1804319E-10, 8.6055318, 5.7289501804, -1742.9305145148,-3.6814974E-04,-4.3749170E-07, 2.1183885E-09, -8.4530982, 7.5540213938, 16100.0685698171, 1.1921869E-04, 2.8238458E-07,-1.3407038E-09,8.0501724, 10.4831850066, 14286.1503796870,-6.0860358E-05, 6.2714140E-08,-1.9984990E-10, -7.6301553, 4.6679834628, 17285.6848046987, 3.0196162E-04, 5.0143862E-07,-2.4271179E-09, -7.4474952, -0.0862513635, 1256.6039104970,-5.3277630E-06, 1.2327842E-09,-1.0887946E-10, 7.3712011, 8.1276304344, 5957.4589549619,-2.1317311E-04,-1.8769697E-07, 9.8648918E-10,7.0629900, 0.9591375719, 33.7570471374,-3.0829302E-05,-3.6967043E-08, 1.7385419E-10, -6.3831491, 9.4966777258, 7004.5133996281, 2.1416722E-04, 3.2425793E-07,-1.5355019E-09, -5.7416071, 13.6527441326, 32409.6866054649,-1.9423071E-04, 5.4047029E-08,-2.6829589E-10, 4.3740095, 18.4814383957, 22128.5152003943,-2.8202511E-04,-1.2313366E-07, 6.2332010E-10,-3.9976134, 7.9669196340, 33524.3151647312, 1.7658291E-04, 4.9092233E-07,-2.3322447E-09, -3.2096876, 13.2398458924, 14985.4400105508,-2.5159493E-04,-1.5449073E-07, 7.2324505E-10, -2.9145404, 12.7093625336, 24499.7476701576, 8.3460748E-05, 3.1497443E-07,-1.5495082E-09, 2.7318890, 16.1258838235, 13799.8237756692,-4.3433786E-04,-3.7354477E-07, 1.8096592E-09,-2.5679459, -2.4418059357, -7072.0875142282,-1.5764051E-04,-2.4917833E-07, 1.0774596E-09, -2.5211990, 7.9551277074, 8470.6667759558,-2.2382863E-04,-1.8523141E-07, 7.6873027E-10, 2.4888871, 5.6426988169, -486.3266040178,-3.7347750E-04,-4.3625891E-07, 2.0095091E-09, 2.1460741, 7.1842488353, -1952.4799803455, 6.4518350E-05, 7.3230428E-08,-2.9472308E-10,1.9777270, 23.1494218585, 39414.2000050930, 1.9936508E-05, 3.7830496E-07,-1.8037978E-09, 1.9336825, 9.4222182890, 33314.7656989005, 6.0925100E-04, 1.0016445E-06,-4.7453563E-09, 1.8707647, 20.8369929680, 30457.2066251194,-1.2971236E-04, 1.2727746E-07,-5.6301898E-10, -1.7529659, 0.4873576771, -8886.0057043583,-3.3771956E-04,-4.6884877E-07,2.2183135E-09,-1.4371624, 7.0979974718, -695.8760698485, 5.9190587E-05, 7.4463212E-08,-4.0360254E-10, -1.3725701, 1.4552986550, -209.5494658307, 4.3266809E-04,5.1072212E-07,-2.4131116E-09, 1.2618162, 7.5108957121, 16728.3705250656, 1.1655481E-04, 2.8300097E-07,-1.3951435E-09};private static final double M11[] = {1.6768000, -0.0431256817, 628.3019552485,-2.6638815E-06, 6.1639211E-10,-5.4439728E-11, 0.5164200, 11.2260974062, 6585.7609102104,-2.1583699E-04,-1.8708058E-07, 9.3204945E-10, 0.4138300, 13.5816519784, 14914.4523349355,-6.3524240E-05, 6.3330532E-08,-2.5428962E-10, 0.3711500, 5.5402729076, 7700.3894694766, 1.5497663E-04, 2.4979472E-07,-1.1318993E-09,0.2756000, 2.3124288905, 8956.9933799736, 1.4964887E-04, 2.5102751E-07,-1.2407788E-09, 0.2459863,-25.6198212459, -2.3011998397, 1.5231275E-04,2.5041111E-07,-1.1863391E-09, 0.0711800, 7.9982533891, 7842.3648207073,-2.2116475E-04,-1.8584780E-07, 8.2317000E-10, 0.0612800, 10.3538079614, 16171.0562454324,-6.8852003E-05, 6.4563317E-08,-3.6316908E-10};private static final double M12[] = { 0.0048700, -0.0431256817, 628.3019552485,-2.6638815E-06, 6.1639211E-10,-5.4439728E-11, 0.0022800,-27.1705318325, -2.3011998397, 1.5231275E-04, 2.5041111E-07,-1.1863391E-09, 0.0015000,11.2260974062, 6585.7609102104,-2.1583699E-04,-1.8708058E-07, 9.3204945E-10}; private static final double M20[] = {18461.2400600, 1.6279052448, 8433.4661576405,-6.4021295E-05,-4.9499477E-09, 2.0216731E-11, 1010.1671484, 3.9834598170, 16762.1575823656, 8.8291456E-05, 2.4546117E-07,-1.1661223E-09, 999.6936555, 0.7276493275, -104.7747329154,2.1633405E-04, 2.5536106E-07,-1.2065558E-09, 623.6524746, 8.7690283983, 7109.2881325435,-2.1668263E-06, 6.8896872E-08,-3.2894608E-10,199.4837596, 9.6692843156, 15647.5290230993,-2.8252217E-04,-1.9141414E-07, 8.9782646E-10, 166.5741153, 6.4134738261, -1219.4032921817,-1.5447958E-04,-1.8151424E-07, 8.5739300E-10, 117.2606951, 12.024*******, 23976.2204478244,-1.3020942E-04, 5.8996977E-08,-2.8851262E-10, 61.9119504, 6.3390143893, 25090.8490070907, 2.4060421E-04, 4.9587228E-07,-2.3524614E-09,33.3572027, 11.1245829706, 15437.9795572686, 1.5014592E-04, 3.1930799E-07,-1.5152852E-09, 31.7596709, 3.0832038997, 8223.9166918098, 3.6864680E-04,5.0577218E-07,-2.3928949E-09, 29.5766003, 8.8121540801, 6480.9861772950,4.9705523E-07, 6.8280480E-08,-2.7450635E-10, 15.5662654, 4.0579192538, -9548.0947169068,-3.0679233E-04,-4.3192536E-07, 2.0437321E-09,15.1215543, 14.3803934601, 32304.9118725496, 2.2103334E-05, 3.0940809E-07,-1.4748517E-09, -12.0941511, 8.7259027166, 7737.5900877920,-4.8307078E-06,6.9513264E-08,-3.8338581E-10, 8.8681426, 9.7124099974, 15019.2270678508,-2.7985829E-04,-1.9203053E-07, 9.5226618E-10, 8.0450400, 0.6687636586, 8399.7091105030,-3.3191993E-05, 3.2017096E-08,-1.5363746E-10,7.9585542, 12.0679645696, 23347.9184925760,-1.2754553E-04, 5.8380585E-08,-2.3407289E-10, 7.4345550, 6.4565995078, -1847.7052474301,-1.5181570E-04,-1.8213063E-07, 9.1183272E-10, -6.7314363, -4.0265854988,-16133.8556271171,-9.0955337E-05,-2.4484477E-07, 1.1116826E-09, 6.5795750, 16.8104074692,14323.3509980023,-2.2066770E-04,-1.1756732E-07, 5.4866364E-10,-6.4600721, 1.5847795630, 9061.7681128890,-6.6685176E-05,-4.3335556E-09,-3.4222998E-11, -6.2964773, 4.8837157343, 25300.3984729215,-1.9206388E-04,-1.4849843E-08, 6.0650192E-11, -5.6323538, -0.7707750092, 733.0766881638,-2.1899793E-04,-2.5474467E-07, 1.1521161E-09, -5.3683961, 6.8263720663, 16204.8433027325,-9.7115356E-05, 2.7023515E-08,-1.3414795E-10,-5.3112784, 3.9403341353, 17390.4595376141, 8.5627574E-05, 2.4607756E-07,-1.2205621E-09, -5.0759179, 0.6845236457, 523.5272223331,2.1367016E-04,2.5597745E-07,-1.2609955E-09, -4.8396143, -1.6710309265, -7805.1642023920, 6.1357413E-05, 5.5663398E-09,-7.4656459E-11, -4.8057401,3.5705615768, -662.0890125485, 3.0927234E-05, 3.6923410E-08,-1.7458141E-10,3.9840545, 8.6945689615, 33419.5404318159, 3.9291696E-04, 7.4628340E-07,-3.5388005E-09, 3.6744619, 19.1659620415, 22652.0424227274,-6.8354947E-05, 1.3284380E-07,-6.3767543E-10, 2.9984815, 20.0662179587, 31190.2833132833,-3.4871029E-04,-1.2746721E-07, 5.8909710E-10, 2.7986413, -2.5281611620,-16971.7070481963, 3.4437664E-04, 2.6526096E-07,-1.2469893E-09,2.4138774, 17.7106633865, 22861.5918885581,-5.0102304E-04,-3.7787833E-07, 1.7754362E-09, 2.1863132, 5.5132179088, -9757.6441827375, 1.2587576E-04, 7.8796768E-08,-3.6937954E-10, 2.1461692, 13.4801375428, 23766.6709819937, 3.0245868E-04, 5.6971910E-07,-2.7016242E-09, 1.7659832, 11.1677086523, 14809.6776020201, 1.5280981E-04, 3.1869159E-07,-1.4608454E-09,-1.6244212, 7.3137297434, 7318.8375983742,-4.3483492E-04,-4.4182525E-07, 2.0841655E-09, 1.5813036, 5.4387584720, 16552.6081165349, 5.2095955E-04, 7.5618329E-07,-3.5792340E-09, 1.5197528, 16.7359480324, 40633.6032972747, 1.7441609E-04, 5.5981921E-07,-2.6611908E-09, 1.5156341, 1.7023646816,-17876.7861416319,-4.5910508E-04,-6.8233647E-07, 3.2300712E-09,1.5102092, 5.4977296450, 8399.6847301375,-3.3094061E-05, 3.1973462E-08,-1.5436468E-10, -1.3178223, 9.6261586339, 16275.8309783478,-2.8518605E-04,-1.9079775E-07, 8.4338673E-10, -1.2642739, 11.9817132061, 24604.5224030729,-1.3287330E-04, 5.9613369E-08,-3.4295235E-10, 1.1918723, 22.4217725310, 39518.9747380084,-1.9639754E-04, 1.2294390E-07,-5.9724197E-10,1.1346110, 14.4235191419, 31676.6099173011,2.4767216E-05,3.0879170E-07,-1.4204120E-09, 1.0857810, 8.8552797618, 5852.6842220465, 3.1609367E-06, 6.7664088E-08,-2.2006663E-10, -1.0193852, 7.2392703065, 33629.0898976466,-3.9751134E-05, 2.3556127E-07,-1.1256889E-09, -0.8227141, 11.0814572888,。
万年历计算方法1。
平年365天(52周+1天),闰年366天(52周+2天)。
平年2月28天,闰年2月29天。
由于公元1月1日设为星期六,故3月1日为星期三。
——注意这个“三”为使算法达到最简,故本算法以“星期”为计算单位。
且选3月1日为基月。
2。
每400年整一闰,或每4年且不为百年的一闰。
(原因:地球绕太阳一周的时间是365天5小时46秒,为了使一年的天数为整数,将一年的天数定为365天,余下的时间积累起来,四年就是23小时15分4秒,将近一天,把这一天加在某年的二月而成29天,该年称为闰年,其它年称为平年。
但四年加一天又多用了44分56秒,这个数积满400年为三天。
因此400年中只能有97个闰年,所以凡能被400整除,或不能被100整除但能被4整除的年份为闰年。
)所以百年%4=0闰或(年%4=0并且年<>0)闰。
3。
每 4年(3个平年+1个闰年)共208周+5天——注意这个“5天”每百年共100*(208周+5天)-1天=5217周+5天——注意这个“5天”(整百年暂设为平年)每400年共4*(5217周+5天)+1天(整400年闰)=20871周+0天——注意这个“0天”和“1天”(4个整百年只有一个闰年)即400年一轮回!(原来万年历400年前是一家)蔡勒(Zeller)公式历史上的某一天是星期几?未来的某一天是星期几?关于这个问题,有很多计算公式(两个通用计算公式和一些分段计算公式),其中最著名的蔡勒(Zeller)公式即w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1公式中的符号含义如下,w:星期;c:世纪-1;y:年(两位数);m:月(m大于等于3,小于等于14,即在蔡勒公式中,某年的1、2月要看作上一年的13、14月来计算,比如2003年1月1日要看作2002年的13月1日来计算);d:日;[ ]代表取整,即只要整数部分。
万年历推算公式万年历可是个挺有意思的东西,能让咱知道过去未来的日子呢!说起万年历的推算公式,这还真有点复杂,但别怕,咱慢慢捋捋。
先来说说公历的推算。
公历一年有 365 天或者 366 天,这得看是不是闰年。
闰年的判断方法就是能被 4 整除但不能被 100 整除的年份,或者能被 400 整除的年份。
比如说 2000 年就是闰年,2100 年就不是闰年。
要推算某一天是星期几,这里有个蔡勒公式。
假设要推算的日期是Y 年 M 月 D 日。
先有个预处理,把 1 月和 2 月当作上一年的 13 月和14 月。
然后公式是:W = [C/4] - 2C + y + [y/4] + [13 * (M + 1) / 5] + d - 1这里的 [] 表示取整运算,W 就是星期几,0 代表星期日,1 代表星期一,以此类推。
C 是世纪数减一,y 是年份的后两位。
举个例子,比如说要算 2023 年 5 月 15 日是星期几。
C 就是 20,y 就是 23,M 是 5,D 是 15。
带入公式算算,就能得出是星期几啦。
我记得有一次,我和朋友约好了周末出去玩。
结果我俩在商量到底是周六还是周日的时候,就用到了这个推算。
朋友还不信,觉得我在瞎蒙。
我就当着他的面,按照公式一步一步算给他看。
算出来是周日的时候,朋友那惊讶的表情,我到现在都还记得。
他直夸我厉害,还说以后要跟我多学学这些实用的小知识。
再来说说农历的推算。
农历的推算就更复杂啦,因为农历要考虑到月亮的运行周期,还有二十四节气等等。
农历一个月有时候是 29 天,有时候是 30 天,一年有时候 12 个月,有时候 13 个月。
农历推算涉及到置闰规则,就是为了让农历和四季的变化尽量相符。
一般来说,如果两个冬至之间有 12 个朔望月,那就不置闰;如果有 13 个朔望月,那就得置闰。
农历的推算还得考虑到天文观测,古代的时候,专门有官员负责观测天象来确定历法呢。
说起来,有一回过年,家里人在讨论哪一天迎财神好。
万年历算法万年历算法一、阳历算法具体算法见函数V oid get_solar_day_date(void),这样阳历日历的星期排法就确定了。
表1:月份 1 2 3 4 5 6 7 8 9 10 11 12闰年31 29 31 30 31 30 31 31 30 31 30 31非闰年31 28 31 30 31 30 31 31 30 31 30 31变量定义:Public:Unsigned int temp_total_day;Unsigned char gc_solar_calendar_year;Unsigned char gc_solar_calendar_month;Unsigned char gc_solar_calendar_date;Unsigned char gc_lunar_calendar_year;Unsigned char gc_lunar_calendar_month;Unsigned char gc_lunar_calendar_date;Unsigned char start_day_of_week;说明:函数get_solar_day_date(void)的输入变量:gc_solar_calendar_year和gc_solar_calendar_month 输出变量:start_day_of_week和temp_total_dayV oid get_solar_day_date(void){unsigned char temp01;/*------calculate what day is the day of the current month and year. Mon~Sun?---*//*条件初始化二次,减少运算数据量. temp_total_day 是int型变量*/start_day_of_week = 2; temp_total_day = 0;calculate_temp = 1;if(gc_solar_calendar_year > 99){start_day_of_week = 6;calculate_temp = 100;}for(temp01 = calculate_temp; temp01<gc_solar_calendar_year; temp01 ){ if(temp014 == 0){start_day_of_week =2;temp_total_day = 366; }else {start_day_of_week =1;temp_total_day = 365;}}for(temp01 = 1;temp01<gc_solar_calendar_month;temp01 ){ switch(temp01){case 1,3,5,7,8,10,12: start_day_of_week =3;temp_total_day =31;break;case 2: if(((gc_solar_calendar_year4) == 0)&&(gc_solar_calendar_year != 200)){start_day_of_week =1; temp_total_day =29;}else {start_day_of_week =0;temp_total_day =28;} break;case 4,6,9,11: start_day_of_week =2; temp_total_day =30; break;}}start_day_of_week =7;/*-end of calculate what day is the day(Mon~Sun?) and total day --*/}二、阴历算法200年需要200 × 2 = 400个字节,构成阴历压缩数据表lunar_calendar_month_table[]如下:const char lunar_calendar_month_table[]={ //从阴历年1900年到2100年/*the total day of each month pointer *//* from 1901~2100*//* (0110)110000001001 (0110)leap month,110000001001lunar month total day: 1:29 0:30*/0x00,0x04,0xad,0x08,0x5a,0x01,0xd5,0x54,0xb4,0x09,0x64,0x05,0x59,0x45,0x95,0x0a,0xa6,0x04,0x55,0x24,0xad,0x08,0x5a,0x62,0xda,0x04,0xb4,0x05,0xb4,0x55,0x52,0x0d,0x94,0x0a,0x4a,0x2a,0x56,0x02,0x6d,0x71,0x6d,0x01,0xda,0x02,0xd2,0x52,0xa9,0x05,0x49,0x0d,0x2a,0x45,0x2b,0x09,0x56,0x01,0xb5,0x20,0x6d,0x01,0x59,0x69,0xd4,0x0a,0xa8,0x05,0xa9,0x56,0xa5,0x04,0x2b,0x09,0x9e,0x38,0xb6,0x08,0xec,0x74,0x6c,0x05,0xd4,0x0a,0xe4,0x6a,0x52,0x05,0x95,0x0a,0x5a,0x42,0x5b,0x04,0xb6,0x04,0xb4,0x22,0x6a,0x05,0x52,0x75,0xc9,0x0a,0x52,0x05,0x35,0x55,0x4d,0x0a,0x5a,0x02,0x5d,0x31,0xb5,0x02,0x6a,0x8a,0x68,0x05,0xa9,0x0a,0x8a,0x6a,0x2a,0x05,0x2d,0x09,0xaa,0x48,0x5a,0x01,0xb5,0x09,0xb0,0x39,0x64,0x05,0x25,0x75,0x95,0x0a,0x96,0x04,0x4d,0x54,0xad,0x04,0xda,0x04,0xd4,0x44,0xb4,0x05,0x54,0x85,0x52,0x0d,0x92,0x0a,0x56,0x6a,0x56,0x02,0x6d,0x02,0x6a,0x41,0xda,0x02,0xb2,0xa1,0xa9,0x05,0x49,0x0d,0x0a,0x6d,0x2a,0x09,0x56,0x01,0xad,0x50,0x6d,0x01,0xd9,0x02,0xd1,0x3a,0xa8,0x05,0x29,0x85,0xa5,0x0c,0x2a,0x09,0x96,0x54,0xb6,0x08,0x6c,0x09,0x64,0x45,0xd4,0x0a,0xa4,0x05,0x51,0x25,0x95,0x0a,0x2a,0x72,0x5b,0x04,0xb6,0x04,0xac,0x52,0x6a,0x05,0xd2,0x0a,0xa2,0x4a,0x4a,0x05,0x55,0x94,0x2d,0x0a,0x5a,0x02,0x75,0x61,0xb5,0x02,0x6a,0x03,0x61,0x45,0xa9,0x0a,0x4a,0x05,0x25,0x25,0x2d,0x09,0x9a,0x68,0xda,0x08,0xb4,0x09,0xa8,0x59,0x54,0x03,0xa5,0x0a,0x91,0x3a,0x96,0x04,0xad,0xb0,0xad,0x04,0xda,0x04,0xf4,0x62,0xb4,0x05,0x54,0x0b,0x44,0x5d,0x52,0x0a,0x95,0x04,0x55,0x22,0x6d,0x02,0x5a,0x71,0xda,0x02,0xaa,0x05,0xb2,0x55,0x49,0x0b,0x4a,0x0a,0x2d,0x39,0x36,0x01,0x6d,0x80,0x6d,0x01,0xd9,0x02,0xe9,0x6a,0xa8,0x05,0x29,0x0b,0x9a,0x4c,0xaa,0x08,0xb6,0x08,0xb4,0x38,0x6c,0x09,0x54,0x75,0xd4,0x0a,0xa4,0x05,0x45,0x55,0x95,0x0a,0x9a,0x04,0x55,0x44,0xb5,0x04,0x6a,0x82,0x6a,0x05,0xd2,0x0a,0x92,0x6a,0x4a,0x05,0x55,0x0a,0x2a,0x4a,0x5a,0x02,0xb5,0x02,0xb2,0x31,0x69,0x03,0x31,0x73,0xa9,0x0a,0x4a,0x05,0x2d,0x55,0x2d,0x09,0x5a,0x01,0xd5,0x48,0xb4,0x09,0x68,0x89,0x54,0x0b,0xa4,0x0a,0xa5,0x6a,0x95,0x04,0xad,0x08,0x6a,0x44,0xda,0x04,0x74,0x05,0xb0,0x25,0x54,0x03,};确定阳历日和阴历日的对应关系的算法:对于其他任何一个阳历日和阴历日的对应关系,都可以通过以下算法求得结果。
/** cal.c** Created on: Apr 10, 2011* Author: Administrator** 现行的格里历是从儒略历演化而来的。
儒略历每4年一个润年,润年366天,平年365天。
* 如果从公元1年算的话,那么凡是能够被4整除的都是润年。
从天文角度看,儒略历这种* 历法是有误差的,到16世纪误差已经达到了10天。
1582年,罗马教皇对儒略历进行了* 一次校定,该年的10-5到10-14这10天被抹掉,并规定凡不能被400整除的世纪年不再* 算为润年,校定之后的儒略历即为现行的格里历。
** 但是英国直到1752年才开始使用格里历,此时时间误差已经达到了11天,原因是1700* 年在儒略历中是润年,而在格里历中是平年。
1752年英国议会决定将本年的9-3到9-13* 这11天抹掉,以同步格里历。
当时美国不是英国的殖民地,所以在美国的日历中也是没有* 1752-9-3到1752-9-13这11天的。
我们知道UNIX系统源于美国,Linux系统源于UNIX,* 这就是为什么当我们在Linux系统中敲"cal 9 1752"这条命令时,会看到一个只有19天* 的9月。
** 以上内容参考自维基百科** 本程序模似Linux中cal命令的部分功能。
允许输入的年分为1...9999。
* 编译器:gcc V4.5.0** 分析:* 1752年是特殊年,1752-9月是特殊年中的特殊月。
** 1752-9-2之前,采用的是儒略历,凡能被4整除都为润年;1752-9-14之后,采用的是* 格里历,不能被400整除的世纪年不再作为润年。
** 格里历闰年计算方法* 世纪年***4000的倍数**3200/1900的倍数400的倍数100的倍数4的倍数* 结果不闰不闰闰不闰闰 * 注:* 3200/1900的倍数是天文科学家研究出来* 增加4000的倍数不闰更准确,但目前只是世纪年还不足4000,因此尚未用途** 格里历在400年的周期中有146,097天,恰好是20,871 星期。
所以,例如,格里历七年、* 407年、807年、1207年、1607年、2007年的日期与星期是完全相同的。
也就是说,格里* 历每400年一个周期。
** 公元1-1-1,按儒略历是周六,按格里历是周一;因1752-9-2之前采用的都是儒略历,所以* 公元1-1-1应该是周六。
* 1752-9-14是周四。
** 公元1-1-1到1752-9-2,日期是连续的,儒略历;公元1752-9-14至今,日期是连续的,格里历。
** 对于给定的一个年(Y)-月(M)-日(D) ,则从公元1-1-1到给定的日期的天数为:* 1752-9-2前:365*(Y-1)+(Y-1)/4+e,其中e表示从Y-1-1到Y-M-D 的天数,* 且这天是该周的第((Y-1)+(Y-1)/4+5+e)%7天。
** 1752-9-14后:365*(Y-1)+(Y-1)/4-(Y-1)/100+(Y-1)/400+e, * 且这天是该周的第((Y-1)+(Y-1)/4-(Y-1)/100+(Y-1)/400+e)%7天。
** 需要注意的是,从1-1-1到1752-9-14之后的某个日期的天数并非实际的天数,它只是根据格里历的* 的规则推算出来的,目的也只是为了得到日期与星期的对应。
** 算法思想:* 对于年历,若能知道本年的1月1日是周几,也就知道了本年的年历分布。
* 对于月历,若能知道本月的1日是周几,也就知道了本月的月历分布。
* 所以关键是正确的推算出给定的一个日期是星期几。
以下为推算方法:* 1752-9-2之前:((Y-1)+(Y-1)/4+5+e)%7* 1752-9-14之后:((Y-1)+(Y-1)/4-(Y-1)/100+(Y-1)/400+e)%7 * 把1800-2199年当成一个周期,对于其后的日期,只需在1800-2199之间找到* 对应的日期,就可以知道是星期几,这样就不用再考虑4000年之后4000的倍数* 不是润年这种情况。
(Y-1800)%400+1800****/#include<stdio.h>#include<string.h>#include<time.h>void PrintHelp();int* CurrentCal();int CheckYear(int year);int CheckMonth(int month);int CheckDay(int year, int month, int day);int IsNum(char *argv);int IsLegalParameter(int argc, char **argv);long StrToLong(char *argv);long Power(int baseNumber, int exponent);void PrintCalendar(int year);void PrintCommonCalendar(int year, int row);void PrintOneQuarter(int year, int mfOfWeek, int mfDays, int msOfWeek, int msDays, int mtOfWeek, int mtDays, int row);void Print1752_3Quarter();void PrintMonthlyCalendar(int year, int month);void PrintMonthName(char *, int year);void PrintCommonMonthlyCalendar(int dayOfWeek, int days);void PrintDayOfWeek(int year, int month, int day);int DayOfWeek(int year, int month, int day);int CurrentDays(int year, int month, int day);int a;//输入的年这个参数的字符串长度,主根用于后面的PrintMonthName(char *, int)函数int main(int argc, char **argv) {int year, month, day;int flag = IsLegalParameter(argc, argv);switch (flag) {case -1:printf("Syntax Error!\n\n");PrintHelp();break;case 0:PrintMonthlyCalendar(*(CurrentCal()), *(CurrentCal() + 1));break;case 1: {a = strlen(*(argv + 1));switch (argc) {case 2:year = StrToLong(*(argv + 1));if (!CheckYear(year)) {break;}printf(" %4d\n\n", year);PrintCalendar(year);break;case 3:year = StrToLong(*(argv + 1));if (!CheckYear(year)) {break;}month = StrToLong(*(argv + 2));month = StrToLong(*(argv + 2));if (!CheckMonth(month)) {break;}PrintMonthlyCalendar(year, month);break;case 4:year = StrToLong(*(argv + 1));if (!CheckYear(year)) {break;}month = StrToLong(*(argv + 2));if (!CheckMonth(month)) {break;}day = StrToLong(*(argv + 3));if (!CheckDay(year, month, day)) {break;}PrintDayOfWeek(year, month, day);break;default:year = StrToLong(*(argv + 1));if (!CheckYear(year)) {break;}month = StrToLong(*(argv + 2));if (!CheckMonth(month)) {break;}day = StrToLong(*(argv + 3));if (!CheckDay(year, month, day)) {break;}PrintDayOfWeek(year, month, day);break;}}default:break;}return 0;}void PrintHelp() {printf("usage:cal [<YEAR> [<MONTH> [<DAY>]]"); }int CheckYear(int year) {printf("cal: year %d not in range 1..9999\n", year);return 0;}return 1;}int CheckMonth(int month) {if (month < 1 || month > 12) {printf("cal: month %d not in range (1..12)\n", month);return 0;}return 1;}int CheckDay(int year, int month, int day) {switch (month) {case 1:if (day < 1 || day > 31) {printf("cal: day %d not in range (1..31)\n", day);return 0;}return 1;break;case 2:if((year < 1753 && year % 4 == 0) || ((year % 4 == 0 && year % 100!= 0) || year % 400 == 0)) {if (day < 1 || day > 29) {printf("cal: day %d not in range (1..29)\n", day);return 0;}}if (day < 1 || day > 28) {printf("cal: day %d not in range (1..28)\n", day);return 0;}return 1;break;case 3:if (day < 1 || day > 31) {printf("cal: day %d not in range (1..31)\n", day);return 0;}return 1;break;case 4:if (day < 1 || day > 30) {printf("cal: day %d not in range (1..30)\n", day);return 0;}return 1;break;case 5:printf("cal: day %d not in range (1..31)\n", day);return 0;}return 1;break;case 6:if (day < 1 || day > 30) {printf("cal: day %d not in range (1..30)\n", day);return 0;}return 1;break;case 7:if (day < 1 || day > 31) {printf("cal: day %d not in range (1..31)\n", day);return 0;}return 1;break;case 8:if (day < 1 || day > 31) {printf("cal: day %d not in range (1..31)\n", day);return 0;}return 1;break;case 9:if (day < 1 || day > 30) {printf("cal: day %d not in range (1..30)\n", day);return 0;}return 1;break;case 10:if (day < 1 || day > 31) {printf("cal: day %d not in range (1..31)\n", day);return 0;}return 1;break;case 11:if (day < 1 || day > 30) {printf("cal: day %d not in range (1..30)\n", day);return 0;}return 1;break;case 12:if (day < 1 || day > 31) {printf("cal: day %d not in range (1..31)\n", day);return 0;}return 1;break;default:break;return 0;}}/*** 以下函数返回一个包含当前年月日的整型数组*/int* CurrentCal() {time_t nowtime;struct tm *timeinfo;time(&nowtime);timeinfo = localtime(&nowtime);int cal[3];cal[0] = timeinfo->tm_year + 1900;cal[1] = timeinfo->tm_mon + 1;cal[2] = timeinfo->tm_mday;return cal;}/*** 以下函数打印年历,以月为单位,分成四行打印,每行打印三个月*/void PrintCalendar(int year) {int i;for (i = 0; i < 4; ++i) {switch (i) {case 0://打印第1行,1-3月的月历printf(" January February March\n");printf("-------------------- ----------------------------------------\n");printf("Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa\n");PrintCommonCalendar(year, 1);break;case 1://打印第2行,4-6月的月历printf(" April May June\n");printf("-------------------- ----------------------------------------\n");printf("Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa\n");PrintCommonCalendar(year, 2);break;case 2://打印第3行,7-9月的月历printf(" July August September\n");printf("-------------------- ----------------------------------------\n");printf("Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa\n");PrintCommonCalendar(year, 3);break;case 3://打印第4行,11-12月的月历printf(" October November December\n");printf("-------------------- ----------------------------------------\n");printf("Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa\n");PrintCommonCalendar(year, 4);break;default:break;}}}/*** 打印出给定年,给定行的3个月的月历。