260 lines
7.0 KiB
C++
260 lines
7.0 KiB
C++
#include<stdio.h>
|
||
#include<stdlib.h>
|
||
#include<math.h>
|
||
|
||
// print函数用于显示菜单时,打印星号和空格。
|
||
void print(char c, int n)
|
||
{
|
||
int i;
|
||
for (i = 1; i <= n; i++)
|
||
{
|
||
putchar(c);
|
||
}
|
||
}
|
||
|
||
// 查询某年某月某日的日期是周几。
|
||
int getWeekday(int year, int month, int day) {
|
||
// 计算1582年10月4日后是星期几的函数
|
||
if (year <= 1582) {
|
||
if (month < 3) {
|
||
year--;
|
||
month += 12;
|
||
}
|
||
int h = (day + 2 * month + 3 * (month + 1) / 5 + year + year / 4 - year / 100 + year / 400) % 7;
|
||
return h + 1;
|
||
}
|
||
// 计算1582年10月4日及以前给定日期是星期几的函数
|
||
else if (year > 1582) {
|
||
if (month < 3) {
|
||
year--;
|
||
month += 12;
|
||
}
|
||
int c = year / 100;
|
||
int y = year % 100;
|
||
int m = month;
|
||
int d = day;
|
||
int w = c / 4 - 2 * c + y + y / 4 + (13 * (m + 1) / 5) + d - 1;
|
||
w = w % 7;
|
||
if (w < 0) {
|
||
w += 7;
|
||
}
|
||
return w;
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
// 检查日期合法性的函数
|
||
int isDateValid(int year, int month, int day) {
|
||
if (month < 1 || month > 12) {
|
||
return 0;
|
||
}
|
||
if (day < 1) {
|
||
return 0;
|
||
}
|
||
if (month == 2) {
|
||
if (((year % 4 == 0 && year % 100!= 0) || year % 400 == 0) && day > 29) {
|
||
return 0;
|
||
}
|
||
else if (day > 28) {
|
||
return 0;
|
||
}
|
||
}
|
||
return 1;
|
||
}
|
||
|
||
// 判断是否为闰年
|
||
int isLeapYear(int year) {
|
||
return ((year % 4 == 0 && year % 100!= 0) || year % 400 == 0);
|
||
}
|
||
|
||
// 获取指定月份的天数
|
||
int getDaysInMonth(int month, int year) {
|
||
int days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||
if (month == 2 && isLeapYear(year)) {
|
||
return 29;
|
||
}
|
||
return days[month - 1];
|
||
}
|
||
|
||
// 输出日历头部(月份和星期)
|
||
void printCalendarHeader(int month, int year) {
|
||
const char* months[] = { "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月" };
|
||
if (year == 1582 && month == 10) {
|
||
printf("\n十月 1582 (Special Month)\n");
|
||
}
|
||
else {
|
||
printf("\n%s %d\n", months[month - 1], year);
|
||
}
|
||
printf("星期一 星期二 星期三 星期四 星期五 星期六 星期日\n");
|
||
}
|
||
|
||
// 输出日历主体(日期部分)
|
||
void printCalendarBody(int month, int year, int format,int day) {
|
||
int daysInMonth = getDaysInMonth(month, year);
|
||
if (month < 3) {
|
||
year--;
|
||
month += 12;
|
||
}
|
||
int k = year % 100;
|
||
int j = year / 100;
|
||
int firstDay =(day + 13 * (month + 1) / 5 + k + k / 4 + j / 4 + 5 * j) % 7-1;
|
||
if (format == 1) { // 单列格式输出逻辑
|
||
if (year == 1582 && month == 10) {
|
||
for (int day = 1; day <=4; day++) {
|
||
printf(" %.2d ", day);
|
||
if ((firstDay + day) % 7 == 0) {
|
||
printf("\n");
|
||
}
|
||
}
|
||
for (int day = 15; day <= daysInMonth; day++) {
|
||
printf(" %.2d ", day);
|
||
if ((firstDay + day) % 7 == 0) {
|
||
printf("\n");
|
||
}
|
||
}
|
||
}else {
|
||
for (int i = 0; i < firstDay; i++) {
|
||
printf(" ");
|
||
}
|
||
for (int day = 1; day <= daysInMonth; day++) {
|
||
printf(" %.2d ",day);
|
||
if((firstDay + day) % 7 == 0){
|
||
printf("\n");
|
||
}
|
||
}
|
||
}
|
||
}else { //双列格式输出逻辑
|
||
if (year == 1582 && month == 10) {
|
||
for (int day = 1; day <=4; day++) {
|
||
printf(" %.2d ", day);
|
||
}
|
||
for (int day = 15; day <= daysInMonth; day++) {
|
||
printf(" %.2d ", day);
|
||
if ((firstDay + day) % 7 == 0) {
|
||
printf("\n");
|
||
}
|
||
}
|
||
if ((firstDay + daysInMonth) % 7!= 0) {
|
||
printf("\n");
|
||
}
|
||
}
|
||
else {
|
||
for (int i = 1; i < firstDay; i++) {
|
||
printf(" ");
|
||
}
|
||
|
||
for (int day = 1; day <= daysInMonth; day++) {
|
||
printf(" %.2d ", day);
|
||
if ((firstDay + day) % 7 == 6) {
|
||
printf("\n");
|
||
}
|
||
}
|
||
if ((firstDay + daysInMonth) % 7!= 6) {
|
||
printf("\n");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
void showMenu()
|
||
{
|
||
putchar('\n');
|
||
print(' ', 10);
|
||
print('*', 60);
|
||
putchar('\n');
|
||
print(' ', 20);
|
||
printf("1--查询某年某月某日的日期是周几\n");
|
||
print(' ', 20);
|
||
printf("2--该年是否为闰年\n");
|
||
print(' ', 20);
|
||
printf("3--输入年份,输出这一年的日历\n");
|
||
print(' ', 10);
|
||
print('*', 60);
|
||
putchar('\n');
|
||
}
|
||
|
||
int main()
|
||
{
|
||
int choice;
|
||
char ifcontinue;
|
||
int year, month, day;
|
||
|
||
showMenu();
|
||
// 选择菜单。
|
||
while (1) {
|
||
printf("\n请选择一个菜单(1-3): ");
|
||
scanf("%d", &choice);
|
||
switch (choice) {
|
||
case 1:
|
||
printf("请输入年份:");
|
||
scanf("%d", &year);
|
||
printf("请输入月份:");
|
||
scanf("%d", &month);
|
||
printf("请输入日期:");
|
||
scanf("%d", &day);
|
||
if (isDateValid(year, month, day)) {
|
||
int weekday = getWeekday(year, month, day);
|
||
switch (weekday) {
|
||
case 0:
|
||
printf("%d年%d月%d日是星期日\n", year, month, day);
|
||
break;
|
||
case 1:
|
||
printf("%d年%d月%d日是星期一\n", year, month, day);
|
||
break;
|
||
case 2:
|
||
printf("%d年%d月%d日是星期二\n", year, month, day);
|
||
break;
|
||
case 3:
|
||
printf("%d年%d月%d日是星期三\n", year, month, day);
|
||
break;
|
||
case 4:
|
||
printf("%d年%d月%d日是星期四\n", year, month, day);
|
||
break;
|
||
case 5:
|
||
printf("%d年%d月%d日是星期五\n", year, month, day);
|
||
break;
|
||
case 6:
|
||
printf("%d年%d月%d日是星期六\n", year, month, day);
|
||
break;
|
||
default:
|
||
printf("计算出现错误\n");
|
||
}
|
||
}
|
||
else {
|
||
printf("输入的日期不合法,请重新输入正确的日期\n");
|
||
}
|
||
break;
|
||
case 2:
|
||
printf("请输入一个年份: ");
|
||
scanf("%d", &year);
|
||
if (isLeapYear(year)) {
|
||
printf("%d年是闰年\n", year);
|
||
}
|
||
else {
|
||
printf("%d年不是闰年\n", year);
|
||
}
|
||
break;
|
||
case 3:
|
||
printf("请输入年份: ");
|
||
scanf("%d", &year);
|
||
int format;
|
||
printf("请选择日历输出格式(1表示单列,2表示双列): ");
|
||
scanf("%d", &format);
|
||
for (int m = 1; m <= 12; m++) {
|
||
printCalendarHeader(m, year);
|
||
printCalendarBody(m, year, format,day);
|
||
}
|
||
break;
|
||
default:
|
||
printf("\n无效\n");
|
||
}
|
||
printf("\n返回请输入6:");
|
||
getchar(); // 处理scanf输入后的换行符
|
||
ifcontinue = getchar();
|
||
if (ifcontinue!= '6') {
|
||
break;
|
||
}
|
||
}
|
||
|
||
return 0;
|
||
}
|