欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

What Day Is It?

程序员文章站 2024-03-17 13:43:22
...

Problem Description

The calendar now in use evolved from the Romans. Julius Caesar codified a calendar system that came to be known as the Julian calendar. In this system, all months have 31 days, except for April, June, September, and November, which have 30 days, and February, which has 28 days in non-leap years, and 29 days in leap years. Also, in this system, leap years happened every four years. That is because the astronomers of ancient Rome computed the year to be 365.25 days long, so that after every four years, one needed to add an extra day to keep the calendar on track with the seasons. To do this, they added an extra day (February 29) to every year that was a multiple of four. 


Julian Rule: 

Every year that is a multiple of 4 is a leap year, i.e. has an extra day (February 29). 

In 1582, Pope Gregory's astronomers noticed that the year was not 365.25 days long, but closer to 365.2425. Therefore, the leap year rule would be revised to the following: 

Gregorian Rule: 

Every year that is a multiple of 4 is a leap year, unless it is a multiple of 100 that is not a multiple of 400. 

To compensate for how the seasons had shifted against the calendar up until that time, the calendar was actually shifted 10 days: the day following October 4, 1582 was declared to be October 15. 


England and its empire (including the United States) didn't switch to the Gregorian calendar system until 1752, when the day following September 2 was declared to be September 14. (The delay was caused by the poor relationship between Henry VIII and the Pope.) 


Write a program that converts dates in the United States using a calendar of the time and outputs weekdays. 


Input

The input will be a series of positive integers greater than zero, three integers per line, which represent dates, one date per line. The format for a date is ``month day year" where month is a number between 1 (which indicates January) and 12 (which indicates December), day is a number between 1 and 31, and year is positive number. 


Output

The output will be the input date and name of the weekday on which the given date falls in the format shown in the sample. An invalid date or nonexistent date for the calendar used in the United States at the time should generate an error message indicating a invalid date. The input will end with three zeroes


Sample Input

11 15 1997
1 1 2000
7 4 1998
2 11 1732
9 2 1752
9 14 1752
4 33 1997
0 0 0


Sample Output

November 15, 1997 is a Saturday
January 1, 2000 is a Saturday
July 4, 1998 is a Saturday
February 11, 1732 is a Friday
September 2, 1752 is a Wednesday 
September 14, 1752 is a Thursday
4/33/1997 is an invalid date.

描述:

现在使用的历法是由罗马人演变而来的。凯撒编纂了一个历法系统,后来被称为朱利安历。在这个系统中,所有月份都有31天,但四月、六月、九月和十一月除外,这些月份有30天,二月在非闰年有28天,闰年有29天。在这个系统中,闰年也是每四年发生一次。这是因为古罗马的天文学家计算出一年的长度是365.25天,所以每4年之后,人们需要增加一天来保持日历与季节同步。为了做到这一点,他们每年增加一天时间(2月29日),是四年的倍数。

朱利安法则:
每年都是4的倍数,是闰年,也就是多一天(2月29日)。
在1582年,Pope Gregory的天文学家注意到这一年不是365.25天长,而是更接近365.2425。因此,闰年规则将修订如下:

格里高利法则:
每年都是4的倍数是闰年,除非是100的倍数不是400的倍数。
为了补偿在此之前的季节变化,日历实际上被改变了10天:1582年10月4日的第二天被宣布为10月15日。

英国和它的帝国(包括美国)直到1752年,也就是9月2日被宣布为9月14日,才改用格里高利历法。(延迟是由于亨利八世与教皇关系不佳造成的。)
编写一个程序,使用平日的时间和输出日历来转换美国的日期。

输入:

输入的是一系列大于零的正整数,每行三个整数,代表日期,每行一个日期。日期的格式是“月日年”,月是1与12之间的数字,1(表示1月),日是1与31之间的数字,年是正数。

输出:

输出将是输入日期和给定日期以示例中显示的格式出现的平日名称。在美国使用的日历的无效日期或不存在日期应产生错误信息,表明日期无效。输入将以三个零结束。

理解:

       假设西元0年1月1日为星期一的基础上进行计算。

  算出给定的日期到这一天经过了几天,计算是星期几就简单了。

AC码:

#include<stdio.h>
const char *DAYS[]={"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
//记录星期的英文拼写 
const char *MONTH[]={"", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
//记录月份的英文拼写 
int mdays[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
//不是闰年时,每月的天数 
int olddate(int m,int d,int y)
{//1752年之前,再加上1582年那少的12天 
	if(y<1752)
	return 1; 
	else if(y==1752&&m<9)
	return 1;
	else if(y==1752&&m==9&&d<=2)
	return 1;
	else
	return 0;
}
int leapyear(int year)
{//两种不同的规则,判断闰年 。是闰年返回1,否则返回0 
	if(year<1752)
	return year%4==0?1:0;
	else
	return (((year%4==0)&&(year%100!=0))||(year%400==0))?1:0;
}
int check(int y,int m,int d)
{//该日期是有效的话,返回1,;否则返回0 
	if(y<=0||m<0||m>12||d<0||d>mdays[m])
	return 0;
	if(y==1752&&m==9&&3<=d&&d<=13)
	return 0;
	return 1;
}
int main(void)
{
	int m,d,y,days,i;
	while(~scanf("%d %d %d",&m,&d,&y)&&(m||d||y))
	{
		mdays[2]=28+leapyear(y);//闰年2月多一天 
		if(check(y,m,d))
		{
			days=d;
			for(i=0;i<m;i++)
			days+=mdays[i];//该填报是这一年中的第几天 ,(闰年比平常多一天 )
			for(i=1;i<y;i++)
			days+=365+leapyear(i);//加上每年的天数,(闰年比平常多一天 )
			printf("%s %d, %d is a %s\n",MONTH[m],d,y,DAYS[(days+(olddate(m,d,y)?12:1))%7]);
		}
		else
		printf("%d/%d/%d is an invalid date.\n",m,d,y);
	}
	return 0;
}

What Day Is It?