C语言根据日期计算星期——基姆拉尔森计算公式

公式

基姆拉尔森计算公式

w = ( day + 2month +3(month+1)/5 + year + year/4 - year/100 +year/400)%7

根据已知公元1年1月1日星期一来推算。
其中,要把一月和二月看成是上一年的十三月和十四月,例:如果是2004-1-10则换算成:2003-13-10来代入公式计算。

代码

#include <stdio.h>

void main()
{
	char weekname[][10]={
		"Monday",
		"Tuseday",
		"Wednesday",
		"Thursday",
		"Friday",
		"Saturday",
		"Sunday"
	};
	int year;
	int month;
	int day;

	printf("请输入年份:");
	scanf("%d",&year);

	printf("请输入月份:");
	scanf("%d",&month);

	printf("请输入日期:");
	scanf("%d",&day);

	if((month == 1) || (month == 2)){
		month += 12;
		year--;
	}
	int w;
	w = (day+2*month+3*(month + 1)/5+year+year/4-year/100+year/400)%7;
	printf("%d/%d/%d 这一天是%s\n",year,month,day,weekname[w]);
}

推导

计算第一个月:

w = (day-1) % 7

计算年:
在不是闰年的情况下,一年365天,365%7=1,因此相同X月X日第二年会比第一年的星期数多1。
闰年一年366天,如果是在闰年当年2月29号之后的日子,星期数会比上一年多2.
为了公式的简洁,将一年的1、2月份归为上一年的13、14月,year-=1,计算年导致的星期数偏差。
闰年的定义是:能被4整除且不能被100整除,或者能被400整除的年份。
因此公式变为

w = ( day-1 + year-1 + year/4 - year/100 +year/400)%7

计算月份:
一个月30天的话,30%7=2,下个月X号的星期数会多2;一个月31天,31%7=3,下个月X号的星期数会多3.

因为闰年的情况在上面计算年时已经考虑过了,因此2月就直接按照28天计算。并且没有1、2月,只有13、14月。

3月:2月28天整除7,1月31天,所以3月X日会比1月X日的星期数多3
4月:3月31天,比上月的星期数多3
5月:4月30天,比上月星期数多2
……
13月:12月31天,比上月的星期数多3
14月:13月31天,比上月的星期数多3
以此类推,可知不是多3就是多2,将2*(month-2)提取出来后,可以得到:

月份比上月星期数增加累计
311
412
502
613
703
814
915
1005
1116
1206
1317
1418

从month=3开始,每月会比上月增加2天外,还会按照11010的规律增加。因此月份的延迟天数应该为:
2*(month-2)+这月之前(含当月)累计多3的月数
从公式中得到启发,3*i/5的结果是:

i3*i3*i/5比i-1增加
0000
1000
2611
3910
41221
51531
61830
72141
82440
92751
103061
113360
123671
133970
144281
154591

可以看到从i=4开始,每次比i-1按照11010的规律增加,和前面从month=3的推导规律是一致的。这月之前(含当月)多3的累计月数为3*(month+1)/5-1:
2*(month-2)+3*(month+1)/5-1
因此:

w = ( day-1 + 2*(month-2)+3*(month+1)/5-1 + year-1 + year/4 - year/100 +year/400)%7

把公式简化一下得到:

w = ( day + 2month +3(month+1)/5 + year + year/4 - year/100 +year/400)%7

参考:https://blog.csdn.net/zjy900507/article/details/80929688
原文是按照o年3月1日推导的,本文是按照1年1月1日推导的。

  • 7
    点赞
  • 0
    评论
  • 10
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 游动-白 设计师:白松林 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值