Files
BlogPosts/Article/YueQian/Code/Mycode/TianShuJiSuan.c
2026-01-19 15:17:28 +08:00

148 lines
4.2 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdio.h>
// 基准日期2004年5月2日星期日
#define BASE_YEAR 2004
#define BASE_MONTH 5
#define BASE_DAY 2
// 闰年判断是闰年返回1否则返回0
int is_leap_year(int year)
{
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}
// 获取指定年份和月份的天数
int get_month_days(int year, int month)
{
int month_days[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if (month == 2 && is_leap_year(year))
{
return 29;
}
return month_days[month];
}
// 计算从"年1月1日"到"年-月-日"的总天数
int days_from_year_start(int year, int month, int day)
{
int total = 0;
for (int m = 1; m < month; m++)
{
total += get_month_days(year, m);
}
total += day;
return total;
}
// 计算两个日期之间的天数差date2 - date1date2需晚于date1
int calculate_days_diff(int year1, int month1, int day1,
int year2, int month2, int day2)
{
int diff = 0;
// 同年直接相减
if (year1 == year2)
{
int days_to_date1 = days_from_year_start(year1, month1, day1);
int days_to_date2 = days_from_year_start(year2, month2, day2);
return days_to_date2 - days_to_date1;
}
// 不同年:分段计算
int total_days_year1 = is_leap_year(year1) ? 366 : 365;
int days_to_date1 = days_from_year_start(year1, month1, day1);
int days_left_in_year1 = total_days_year1 - days_to_date1;
for (int y = year1 + 1; y < year2; y++)
{
diff += is_leap_year(y) ? 366 : 365;
}
int days_to_date2 = days_from_year_start(year2, month2, day2);
diff += days_left_in_year1 + days_to_date2;
return diff;
}
int zeller_calc_weekday(int year, int month, int day)
{
int y, c, m, d;
if (month < 3)
{
m = month + 12;
y = year - 1;
}
else
{
m = month;
y = year;
}
c = y / 100;
y = y % 100;
d = day;
int w = (y + y/4 + c/4 - 2*c + (26*(m+1))/10 + d - 1) % 7;
if (w < 0)
w += 7;
w = w % 7;
return w;
}
int main(void)
{
int target_year, target_month, target_day;
// 星期映射表索引0=星期日1=星期一...6=星期六
char *weekdays[] = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
while(1)
{
printf("依次输入 年 月 日(需晚于%d年%d月%d日", BASE_YEAR, BASE_MONTH, BASE_DAY);
scanf("%d%d%d", &target_year, &target_month, &target_day);
// 输入合法性校验
if (target_year < BASE_YEAR)
{
printf("年份应在%d年及之后\n", BASE_YEAR);
continue;
}
if (target_month < 1 || target_month > 12)
{
printf("月份输入错误请输入1-12之间的数字\n");
continue;
}
int days_of_month = get_month_days(target_year, target_month);
if (target_day < 1 || target_day > days_of_month)
{
printf("%d年%d月没有%d日\n", target_year, target_month, target_day);
continue;
}
if (target_year == BASE_YEAR)
{
if (target_month < BASE_MONTH ||
(target_month == BASE_MONTH && target_day < BASE_DAY))
{
printf("日期需晚于%d年%d月%d日\n", BASE_YEAR, BASE_MONTH, BASE_DAY);
continue;
}
}
// 计算天数差
int total_days = calculate_days_diff(BASE_YEAR, BASE_MONTH, BASE_DAY,
target_year, target_month, target_day);
// 用蔡勒公式计算星期几
int weekday = zeller_calc_weekday(target_year, target_month, target_day);
// 输出结果
printf("%d年%d月%d日距%d年%d月%d日共%d天\n",
target_year, target_month, target_day,
BASE_YEAR, BASE_MONTH, BASE_DAY, total_days);
// 显示星期几
printf("%d年%d月%d日 是 %s\n", target_year, target_month, target_day, weekdays[weekday]);
printf("------------------------------------------------------\n");
}
return 0;
}