//编写一个日历系统
//功能要求:
//1、输入一个年份,输出是在屏幕上显示该年的日历。假定输入的年份在 1940-2040 之间
//2、输入年月,输出该月的日历
//3、输入年月日,输出距今天还有多少天,星期几,是否是公历节日。
#include<stdio.h>
#include<time.h>
#define isLeap(x) x%100!=0&&x%4==01|x%400==0?1:0
int dayOfMonth[13][2] = {
0,0,
31,31,
28,29,
31,31,
30,30,
31,31,
30,30,
31,31,
31,31,
30,30,
31,31,
30,30,
31,31
};
struct Date{
int Year,Month,Day;
void nextDay(){
Day++;
if(Day>dayOfMonth[Month][isLeap(Year)]){
Day=1;
Month++;
if(Month>12){
Month=1;
Year++;
}
}
}
}; //日期类,方便计算日期的推移
int buf[2040][13][32];
char weekName[7][20]=
{
"星期天",
"星期一",
"星期二",
"星期三",
"星期四",
"星期五",
"星期六"
};
int main()
{
Date tmp;
int cnt=0;
tmp.Year=1940;
tmp.Month=1;
tmp.Day=1;
while (tmp.Year != 2041){
buf[tmp.Year][tmp.Month][tmp.Day] = cnt;
tmp.nextDay();
cnt++;
}
//预处理出每一天与 1940年1月1日的天数差
void func1(int i); //输入为年月日时调用 func1
void func2(int i); //输入为年月时调用 func2
void func3(int i); //输入为年时调用 func3
int input, year, month, day;
printf("请输入 1940年到2040年之间的年,年月或年月日 ,中间不要有空格(如19920218):\n");
while (scanf("%d", &input) != EOF)
{
if (input / 10000000 != 0) func1(input);
else if (input / 100000 != 0) func2(input);
else if (input / 1000 != 0) func3(input);
}//判断输入的是年、年月还是年月日
}
void func1 (int i){
bool test_year(int i);
bool test_month(int i);
bool test_day(int i);
// 调用系统时间
time_t tval;
struct tm *now;
tval=time(NULL);
now = localtime(&tval);
int today_year=now->tm_year+1900;
int today_month=now->tm_mon+1;
int today_day=now->tm_mday;
// 调用结束
//把输入的数据拆分成年、月、日
int input_year=i/10000;
int input_month=i/100%100;
int input_day=i%100;
// 拆分结束
if(!test_year(input_year)) printf(" 输入的格式有误,请重新输入! \n");
else if(!test_month(input_month)) printf(" 输入的格式有误,请重新输入! \n");
else if(!test_day(i)) printf("输入的格式有误,请重新输入! \n");
else{
int
days=buf[input_year][input_month][input_day]-buf[today_year][today_month][today_day]; //计算给点日期与今日日期的天数间隔(可能为负数)
printf("距今天还有%d天,",days);
int d=buf[input_year][input_month][input_day]+1; //1940年1月1日为星期一,对应数组下标为 1,则计算 1经过 buf[input_year][input_month][input_day] 天后的下标
printf("%s",weekName[(d%7+7)%7]); // 将计算后得出的下标用 7对其取模,并且保证其为非负数,则该下标即为答案所对应的下标,输出即可
if(input_month==1&&input_day==1) printf(" ,元旦节");
if(input_month==2&&input_day==14) printf(" ,情人节");
if(input_month==3&&input_day==8) printf(" ,妇女节");
if(input_month==3&&input_day==12) printf(" ,植树节");
if(input_month==4&&input_day==1) printf(" ,愚人节");
if(input_month==5&&input_day==1) printf(" ,劳动节");
if(input_month==5&&input_day==4) printf(" ,青年节");
if(input_month==6&&input_day==1) printf(" ,儿童节");
if(input_month==7&&input_day==1) printf(" ,建党节");
if(input_month==8&&input_day==1) printf(" ,建军节");
if(input_month==9&&input_day==10) printf(" ,教师节");
if(input_month==10&&input_day==1) printf(" ,国庆节");
if(input_month==12&&input_day==25) printf(" ,圣诞节");
printf("。\n");
}
}//输入是年月日时,输出能今天还有多少天,星期几,是否是公历节日
void func2(int i){
bool test_year(int i);
bool test_month(int i);
//把输入的数据拆分成年、月
int input_year=i/100;
int input_month=i%100;
// 拆分结束
if(!test_year(input_year)) printf(" 输入的格式有误,请重新输入! \n");
else if(!test_month(input_month)) printf(" 输入的格式有误,请重新输入! In");
else{
for(int i=0;i<7;i++) printf("%s\t",weekName[i]);
printf("\n");
int days=buf[input_year][input_month][1];
days+=1;//1940年1月1日为星期一,对应数组下标为 1,则计算 1经过 days天后的下标
int firstDay=(days%7+7)%7;//计算该月 1号是星期几
int array[6][7]={0};//设置输出日历的数组,初始化为 0
array[0][firstDay]=1;
for (int j = firstDay; j < 6; j++) array[0][j + 1] = array[0][j] + 1;
array[1][0]=array[0][6]+ 1;
for(int i=1;i<6;i++){
for(int j=0;j<7;j++){
if(i==5&&j==6) break;
else if(j==6) array[i+ 1][0]=array[i][6]+1;
else array[i][j+1]=array[i][j]+1;
}
}
for(int i=0;i<6;i++){
for(int j=0;j<7;j++){
if(i==0&&j==0&&array[i][j]==0) printf("");
else if(i==0&&array[i][j]==0) printf("\t");
else if(i!=0&&array[i][j]>dayOfMonth[input_month][isLeap(input_year)])printf("");//把大于该月天数的数不输出
else if(j==0) printf(" %d",array[i][j]);
else if(j==6) printf("t %d\n",array[i][j]);
else printf("t %d",array[i][j]);
}
}
printf("n");
}
} //输入是年月时,输出该月的日历
void func3(int i){
bool test_year(int i);
if(!test_year(i))printf("输入的格式有误,请重新输入! \n");
else{
for(int j=0;j<12;j++){
printf("\t \t \t %d 月\n",j+1);
func2(i*100+j+1);
}
}
} //输入是年时,输出是在屏幕上显示该年的日历,假定输入的年份在 1940-2040 年之间
bool test_year(int i){
if(i>1939 && i<2041) return true;
else return false;
}
bool test_month(int i) {
if (i > 0 && i < 13) return true;
else return false;
}
bool test_day(int i) {
int y = i / 10000;
int m = i / 100 % 100;
int d = i % 100;
if (d > 0 && d < dayOfMonth[m][isLeap(y)] + 1) return true;
else return false;
}


//编写一个日历系统
//功能要求:
//1、输入一个年份,输出是在屏幕上显示该年的日历。假定输入的年份在 1940-2040 之间
//2、输入年月,输出该月的日历
//3、输入年月日,输出距今天还有多少天,星期几,是否是公历节日。
#include<stdio.h>
#include<time.h>
#define isLeap(x) x%100!=0&&x%4==01|x%400==0?1:0
int dayOfMonth[13][2] = {
0,0,
31,31,
28,29,
31,31,
30,30,
31,31,
30,30,
31,31,
31,31,
30,30,
31,31,
30,30,
31,31
};
struct Date {
int Year, Month, Day;
void nextDay() {
Day++;
if (Day > dayOfMonth[Month][isLeap(Year)]) {
Day = 1;
Month++;
if (Month > 12) {
Month = 1;
Year++;
}
}
}
}; //日期类,方便计算日期的推移
int buf[2040][13][32];
char weekName[7][20] =
{
"星期天",
"星期一",
"星期二",
"星期三",
"星期四",
"星期五",
"星期六"
};
int main()
{
Date tmp;
int cnt = 0;
tmp.Year = 1940;
tmp.Month = 1;
tmp.Day = 1;
while (tmp.Year != 2041) {
buf[tmp.Year][tmp.Month][tmp.Day] = cnt;
tmp.nextDay();
cnt++;
}
//预处理出每一天与 1940年1月1日的天数差
void func1(int i); //输入为年月日时调用 func1
void func2(int i); //输入为年月时调用 func2
void func3(int i); //输入为年时调用 func3
int input, year, month, day;
printf("请输入 1940年到2040年之间的年,年月或年月日 ,中间不要有空格(如19920218):\n");
while (scanf("%d", &input) != EOF)
{
if (input / 10000000 != 0) func1(input);
else if (input / 100000 != 0) func2(input);
else if (input / 1000 != 0) func3(input);
}//判断输入的是年、年月还是年月日
}
void func1(int i) {
bool test_year(int i);
bool test_month(int i);
bool test_day(int i);
// 调用系统时间
time_t tval;
struct tm* now;
tval = time(NULL);
now = localtime(&tval);
int today_year = now->tm_year + 1900;
int today_month = now->tm_mon + 1;
int today_day = now->tm_mday;
// 调用结束
//把输入的数据拆分成年、月、日
int input_year = i / 10000;
int input_month = i / 100 % 100;
int input_day = i % 100;
// 拆分结束
if (!test_year(input_year)) printf(" 输入的格式有误,请重新输入! \n");
else if (!test_month(input_month)) printf(" 输入的格式有误,请重新输入! \n");
else if (!test_day(i)) printf("输入的格式有误,请重新输入! \n");
else {
int
days = buf[input_year][input_month][input_day] - buf[today_year][today_month][today_day]; //计算给点日期与今日日期的天数间隔(可能为负数)
printf("距今天还有%d天,", days);
int d = buf[input_year][input_month][input_day] + 1; //1940年1月1日为星期一,对应数组下标为 1,则计算 1经过 buf[input_year][input_month][input_day] 天后的下标
printf("%s", weekName[(d % 7 + 7) % 7]); // 将计算后得出的下标用 7对其取模,并且保证其为非负数,则该下标即为答案所对应的下标,输出即可
if (input_month == 1 && input_day == 1) printf(" ,元旦节");
if (input_month == 2 && input_day == 14) printf(" ,情人节");
if (input_month == 3 && input_day == 8) printf(" ,妇女节");
if (input_month == 3 && input_day == 12) printf(" ,植树节");
if (input_month == 4 && input_day == 1) printf(" ,愚人节");
if (input_month == 5 && input_day == 1) printf(" ,劳动节");
if (input_month == 5 && input_day == 4) printf(" ,青年节");
if (input_month == 6 && input_day == 1) printf(" ,儿童节");
if (input_month == 7 && input_day == 1) printf(" ,建党节");
if (input_month == 8 && input_day == 1) printf(" ,建军节");
if (input_month == 9 && input_day == 10) printf(" ,教师节");
if (input_month == 10 && input_day == 1) printf(" ,国庆节");
if (input_month == 12 && input_day == 25) printf(" ,圣诞节");
printf("。\n");
}
}//输入是年月日时,输出能今天还有多少天,星期几,是否是公历节日
void func2(int i) {
bool test_year(int i);
bool test_month(int i);
//把输入的数据拆分成年、月
int input_year = i / 100;
int input_month = i % 100;
// 拆分结束
if (!test_year(input_year)) printf(" 输入的格式有误,请重新输入! \n");
else if (!test_month(input_month)) printf(" 输入的格式有误,请重新输入! In");
else {
for (int i = 0; i < 7; i++) printf("%s\t", weekName[i]);
printf("\n");
int days = buf[input_year][input_month][1];
days += 1;//1940年1月1日为星期一,对应数组下标为 1,则计算 1经过 days天后的下标
int firstDay = (days % 7 + 7) % 7;//计算该月 1号是星期几
int array[6][7] = { 0 };//设置输出日历的数组,初始化为 0
array[0][firstDay] = 1;
for (int j = firstDay; j < 6; j++) array[0][j + 1] = array[0][j] + 1;
array[1][0] = array[0][6] + 1;
for (int i = 1; i < 6; i++) {
for (int j = 0; j < 7; j++) {
if (i == 5 && j == 6) break;
else if (j == 6) array[i + 1][0] = array[i][6] + 1;
else array[i][j + 1] = array[i][j] + 1;
}
}
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 7; j++) {
if (i == 0 && j == 0 && array[i][j] == 0) printf("");
else if (i == 0 && array[i][j] == 0) printf("\t");
else if (i != 0 && array[i][j] > dayOfMonth[input_month][isLeap(input_year)])printf("");//把大于该月天数的数不输出
else if (j == 0) printf(" %d", array[i][j]);
else if (j == 6) printf("\t %d\n", array[i][j]);
else printf("\t %d", array[i][j]);
}
}
printf("\n");
}
} //输入是年月时,输出该月的日历
void func3(int i) {
bool test_year(int i);
if (!test_year(i))printf("输入的格式有误,请重新输入! \n");
else {
for (int j = 0; j < 12; j++) {
printf("\t \t \t %d 月\n", j + 1);
func2(i * 100 + j + 1);
}
}
} //输入是年时,输出是在屏幕上显示该年的日历,假定输入的年份在 1940-2040 年之间
bool test_year(int i) {
if (i > 1939 && i < 2041) return true;
else return false;
}
bool test_month(int i) {
if (i > 0 && i < 13) return true;
else return false;
}
bool test_day(int i) {
int y = i / 10000;
int m = i / 100 % 100;
int d = i % 100;
if (d > 0 && d < dayOfMonth[m][isLeap(y)] + 1) return true;
else return false;
}
//编写一个日历系统
//功能要求:
//1、输入一个年份,输出是在屏幕上显示该年的日历。假定输入的年份在 1940-2040 之间
//2、输入年月,输出该月的日历
//3、输入年月日,输出距今天还有多少天,星期几,是否是公历节日。
#include <stdio.h>
#include <time.h>
#include <stdbool.h>
int dayOfMonth[13][2] = {
0, 0,
31, 31,
28, 29,
31, 31,
30, 30,
31, 31,
30, 30,
31, 31,
31, 31,
30, 30,
31, 31,
30, 30,
31, 31};
struct Date
{
int Year, Month, Day;
}; //日期类,方便计算日期的推移
bool isLeap(int x){
return x % 100 != 0 && x % 4 == 0 || x % 400 == 0;
}
void nextDay(struct Date *date)
{
date->Day++;
if (date->Day > dayOfMonth[date->Month][isLeap(date->Year)])
{
date->Day = 1;
date->Month++;
if (date->Month > 12)
{
date->Month = 1;
date->Year++;
}
}
}
int buf[2040][13][32];
char weekName[7][20] =
{
"星期天",
"星期一",
"星期二",
"星期三",
"星期四",
"星期五",
"星期六"};
int main()
{
struct Date tmp;
int cnt = 0;
tmp.Year = 1940;
tmp.Month = 1;
tmp.Day = 1;
while (tmp.Year != 2041)
{
buf[tmp.Year][tmp.Month][tmp.Day] = cnt;
nextDay(&tmp);
cnt++;
}
//预处理出每一天与 1940年1月1日的天数差
void func1(int i); //输入为年月日时调用 func1
void func2(int i); //输入为年月时调用 func2
void func3(int i); //输入为年时调用 func3
int input, year, month, day;
printf("请输入 1940年到2040年之间的年,年月或年月日 ,中间不要有空格(如19920218):\n");
while (scanf("%d", &input) != EOF)
{
if (input / 10000000 != 0)
func1(input);
else if (input / 100000 != 0)
func2(input);
else if (input / 1000 != 0)
func3(input);
} //判断输入的是年、年月还是年月日
}
void func1(int i)
{
bool test_year(int i);
bool test_month(int i);
bool test_day(int i);
// 调用系统时间
time_t tval;
struct tm *now;
tval = time(NULL);
now = localtime(&tval);
int today_year = now->tm_year + 1900;
int today_month = now->tm_mon + 1;
int today_day = now->tm_mday;
// 调用结束
//把输入的数据拆分成年、月、日
int input_year = i / 10000;
int input_month = i / 100 % 100;
int input_day = i % 100;
// 拆分结束
if (!test_year(input_year))
printf(" 输入的格式有误,请重新输入! \n");
else if (!test_month(input_month))
printf(" 输入的格式有误,请重新输入! \n");
else if (!test_day(i))
printf("输入的格式有误,请重新输入! \n");
else
{
int
days = buf[input_year][input_month][input_day] - buf[today_year][today_month][today_day]; //计算给点日期与今日日期的天数间隔(可能为负数)
printf("距今天还有%d天,", days);
int d = buf[input_year][input_month][input_day] + 1; //1940年1月1日为星期一,对应数组下标为 1,则计算 1经过 buf[input_year][input_month][input_day] 天后的下标
printf("%s", weekName[(d % 7 + 7) % 7]); // 将计算后得出的下标用 7对其取模,并且保证其为非负数,则该下标即为答案所对应的下标,输出即可
if (input_month == 1 && input_day == 1)
printf(" ,元旦节");
if (input_month == 2 && input_day == 14)
printf(" ,情人节");
if (input_month == 3 && input_day == 8)
printf(" ,妇女节");
if (input_month == 3 && input_day == 12)
printf(" ,植树节");
if (input_month == 4 && input_day == 1)
printf(" ,愚人节");
if (input_month == 5 && input_day == 1)
printf(" ,劳动节");
if (input_month == 5 && input_day == 4)
printf(" ,青年节");
if (input_month == 6 && input_day == 1)
printf(" ,儿童节");
if (input_month == 7 && input_day == 1)
printf(" ,建党节");
if (input_month == 8 && input_day == 1)
printf(" ,建军节");
if (input_month == 9 && input_day == 10)
printf(" ,教师节");
if (input_month == 10 && input_day == 1)
printf(" ,国庆节");
if (input_month == 12 && input_day == 25)
printf(" ,圣诞节");
printf("。\n");
}
} //输入是年月日时,输出能今天还有多少天,星期几,是否是公历节日
void func2(int i)
{
bool test_year(int i);
bool test_month(int i);
//把输入的数据拆分成年、月
int input_year = i / 100;
int input_month = i % 100;
// 拆分结束
if (!test_year(input_year))
printf(" 输入的格式有误,请重新输入! \n");
else if (!test_month(input_month))
printf(" 输入的格式有误,请重新输入! In");
else
{
for (int i = 0; i < 7; i++)
printf("%s\t", weekName[i]);
printf("\n");
int days = buf[input_year][input_month][1];
days += 1; //1940年1月1日为星期一,对应数组下标为 1,则计算 1经过 days天后的下标
int firstDay = (days % 7 + 7) % 7; //计算该月 1号是星期几
int array[6][7] = {0}; //设置输出日历的数组,初始化为 0
array[0][firstDay] = 1;
for (int j = firstDay; j < 6; j++)
array[0][j + 1] = array[0][j] + 1;
array[1][0] = array[0][6] + 1;
for (int i = 1; i < 6; i++)
{
for (int j = 0; j < 7; j++)
{
if (i == 5 && j == 6)
break;
else if (j == 6)
array[i + 1][0] = array[i][6] + 1;
else
array[i][j + 1] = array[i][j] + 1;
}
}
for (int i = 0; i < 6; i++)
{
for (int j = 0; j < 7; j++)
{
if (i == 0 && j == 0 && array[i][j] == 0)
printf("");
else if (i == 0 && array[i][j] == 0)
printf("\t");
else if (i != 0 && array[i][j] > dayOfMonth[input_month][isLeap(input_year)])
printf(""); //把大于该月天数的数不输出
else if (j == 0)
printf(" %d", array[i][j]);
else if (j == 6)
printf("\t %d\n", array[i][j]);
else
printf("\t %d", array[i][j]);
}
}
printf("\n");
}
} //输入是年月时,输出该月的日历
void func3(int i)
{
bool test_year(int i);
if (!test_year(i))
printf("输入的格式有误,请重新输入! \n");
else
{
for (int j = 0; j < 12; j++)
{
printf("\t \t \t %d 月\n", j + 1);
func2(i * 100 + j + 1);
}
}
} //输入是年时,输出是在屏幕上显示该年的日历,假定输入的年份在 1940-2040 年之间
bool test_year(int i)
{
if (i > 1939 && i < 2041)
return true;
else
return false;
}
bool test_month(int i)
{
if (i > 0 && i < 13)
return true;
else
return false;
}
bool test_day(int i)
{
int y = i / 10000;
int m = i / 100 % 100;
int d = i % 100;
if (d > 0 && d < dayOfMonth[m][isLeap(y)] + 1)
return true;
else
return false;
}