232 lines
5.1 KiB
C++
232 lines
5.1 KiB
C++
#include<bits/stdc++.h>
|
||
using namespace std;
|
||
|
||
// 判断是否为闰年
|
||
bool run_nian(int year) {
|
||
return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
|
||
}
|
||
|
||
// 计算某年某月的天数
|
||
int TIANSHU(int year, int month) {
|
||
static int days[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||
if (month == 2 && run_nian(year))
|
||
return 29;
|
||
|
||
return days[month];
|
||
}
|
||
|
||
// 计算指定日期是星期几(蔡勒公式)
|
||
int WEEK(int year, int month, int day) {
|
||
int week;
|
||
if (month < 3) {
|
||
month += 12;
|
||
year--;
|
||
}
|
||
int c = year / 100;
|
||
int y = year % 100;
|
||
if ((year < 1582) || (year == 1582 && month <= 10 && day <= 4))
|
||
week = (day + 1 + 2 * month + 3 * (month + 1) / 5 + year + year / 4 + 5) % 7;
|
||
else if ((year > 1582) || (year == 1582 && month >= 10 && day >= 10))
|
||
week = (c / 4 - 2 * c + y + y / 4 + 13 * (month + 1) / 5 + day - 1) % 7;
|
||
else
|
||
week = 8;
|
||
if (week < 0)
|
||
week += 7;
|
||
return week;
|
||
}
|
||
|
||
// 打印单月日历
|
||
void danlie(int year, int month) {
|
||
if (year != 1582) {
|
||
cout << " " << year << "年" << month << "月\n";
|
||
cout << " 一 二 三 四 五 六 日\n";
|
||
|
||
int weekday = WEEK(year, month, 1);
|
||
for (int i = 0; i < weekday % 7; i++)
|
||
cout << " ";
|
||
|
||
int days = TIANSHU(year, month);
|
||
for (int i = 1; i <= days; ++i) {
|
||
cout << setw(3) << i;
|
||
if ((weekday + i) % 7 == 0)
|
||
cout << "\n";
|
||
}
|
||
cout << "\n";
|
||
} else {
|
||
if (month != 10) {
|
||
cout << " " << year << "年" << month << "月\n";
|
||
cout << " 一 二 三 四 五 六 日\n";
|
||
|
||
int weekday = WEEK(year, month, 1);
|
||
for (int i = 0; i < weekday % 7; i++)
|
||
cout << " ";
|
||
|
||
int days = TIANSHU(year, month);
|
||
for (int i = 1; i <= days; ++i) {
|
||
cout << setw(3) << i;
|
||
if ((weekday + i) % 7 == 0)
|
||
cout << "\n";
|
||
}
|
||
cout << "\n";
|
||
}
|
||
|
||
else {
|
||
cout << " " << year << "年" << month << "月\n";
|
||
cout << " 一 二 三 四 五 六 日\n";
|
||
|
||
int weekday = WEEK(year, month, 1);
|
||
for (int i = 0; i < weekday % 7; i++)
|
||
cout << " ";
|
||
|
||
int days = TIANSHU(year, month);
|
||
for (int i = 1; i <= days; ++i) {
|
||
if (i <= 4 || i > 14)
|
||
cout << setw(3) << i;
|
||
else
|
||
continue;
|
||
if (i == 16 || i == 23 || i == 30)
|
||
cout << "\n";
|
||
}
|
||
cout << "\n";
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
// 打印双月日历(并排显示两个月)
|
||
void shuang_yueli(int year, int month) {
|
||
int days1 = TIANSHU(year, month);
|
||
int days2 = TIANSHU(year, month + 1);
|
||
|
||
cout << " " << year << "年" << month << "月 - " << year << "年" << month + 1 << "月\n";
|
||
cout << " 一 二 三 四 五 六 日 一 二 三 四 五 六 日\n";
|
||
|
||
int weekday1 = WEEK(year, month, 1);
|
||
int weekday2 = WEEK(year, month + 1, 1);
|
||
int i, j, ij1, ij2;
|
||
for (int m = 0; m < weekday1; ++m)
|
||
cout << " ";
|
||
for (i = 1; i < days1; i++) {
|
||
for (j = 1; j < days2; j++) {
|
||
for (ij1 = 1; ij1 <= (weekday1 + i) % 7; ij1++) {
|
||
cout << setw(3) << i;
|
||
i++;
|
||
}
|
||
for (int m = 0; m < weekday2; ++m)
|
||
cout << " ";
|
||
for (ij2 = 1; ij2 <= (weekday2 + j) % 7; ij2++) {
|
||
cout << setw(3)<< j;
|
||
j++;
|
||
if((weekday2+j)%7==0)
|
||
{
|
||
cout<<"\n";
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 显示菜单并获取用户选择
|
||
int menu() {
|
||
int choice;
|
||
cout << "万年历程序菜单:\n";
|
||
cout << "1. 查询某年某月某日是周几及该年是否为闰年\n";
|
||
cout << "2. 输出指定年份的单月日历\n";
|
||
cout << "3. 输出指定年份的双月日历\n";
|
||
cout << "4. 退出程序\n";
|
||
cout << "请输入你的选择:";
|
||
while (scanf("%d", &choice) != 1) {
|
||
while (getchar() != '\n') ;
|
||
printf("无效的选择,请重新输入\n");
|
||
}
|
||
return choice;
|
||
}
|
||
|
||
// 获取有效年份输入
|
||
int wannianli() {
|
||
int year;
|
||
cout << "请输入年份(公元后):";
|
||
while (scanf("%d", &year) != 1) {
|
||
while (getchar() != '\n') ;
|
||
printf("无效的选择,请重新输入\n");
|
||
}
|
||
return year;
|
||
}
|
||
|
||
// 获取有效月份输入
|
||
int month_1() {
|
||
int month;
|
||
cout << "请输入月份(1 - 12):";
|
||
while (scanf("%d", &month) != 1) {
|
||
while (getchar() != '\n') ;
|
||
printf("无效的选择,请重新输入\n");
|
||
}
|
||
if (month > 12 || month < 1) {
|
||
printf("无效的选择,请重新输入\n");
|
||
}
|
||
return month;
|
||
}
|
||
|
||
// 获取有效日期输入
|
||
int DAY(int year, int month) {
|
||
int date;
|
||
cout << "请输入日期(1 - " << TIANSHU(year, month) << "):";
|
||
while (scanf("%d", &date) != 1) {
|
||
while (getchar() != '\n') ;
|
||
printf("无效的选择,请重新输入\n");
|
||
}
|
||
return date;
|
||
}
|
||
|
||
int main() {
|
||
int choice;
|
||
do {
|
||
choice = menu();
|
||
|
||
switch (choice) {
|
||
case 1: {
|
||
int year = wannianli();
|
||
int month = month_1();
|
||
int date = DAY(year, month);
|
||
|
||
bool leap = run_nian(year);
|
||
int weekday = WEEK(year, month, date);
|
||
if (weekday == 0)
|
||
cout << year << "年" << month << "月" << date << "日是星期天。\n";
|
||
if (weekday == 8)
|
||
cout << year << "年" << month << "月" << date << "日不存在。\n";
|
||
if (weekday < 8 && weekday > 0)
|
||
cout << year << "年" << month << "月" << date << "日是星期" << weekday << "。\n";
|
||
cout << year << (leap ? "是闰年。\n" : "不是闰年。\n");
|
||
break;
|
||
}
|
||
case 2: {
|
||
int year = wannianli();
|
||
for (int month = 1; month <= 12; ++month) {
|
||
danlie(year, month);
|
||
}
|
||
break;
|
||
}
|
||
case 3: {
|
||
int year = wannianli();
|
||
for (int month = 1; month < 12; month += 2) {
|
||
shuang_yueli(year, month);
|
||
}
|
||
break;
|
||
}
|
||
case 4:
|
||
cout << "程序已退出。\n";
|
||
break;
|
||
default:
|
||
cout << "无效的选择,请重新输入。\n";
|
||
break;
|
||
}
|
||
} while (choice != 4);
|
||
|
||
return 0;
|
||
}
|