收集一些日历中常用的功能
//判断是不是闰年 unsigned char is_leap_year(int year) { return (year % 400 == 0)||(year % 4 == 0 && year % 100 != 0); }
//今天是星期几 int ZellerWeek(int year, int month, int day) { int m = month; int d = day; if (month <= 2) { year--; m = month + 12; } int y = year % 100; int c = year / 100; int w = (y + y / 4 + c / 4 - 2 * c + (13 * (m + 1) / 5) + d - 1) % 7; if (w < 0) { w += 7; } return w; } //第二种写法
u8 const table_week[12]={0,3,3,6,1,4,6,2,5,0,3,5}; //月修正数据表
char SRTC_Get_Week(u16 year,u8 month,u8 day) //计算星期几
{
u16 temp2;
u8 yearH,yearL;
yearH=year/100; yearL=year%100;//取年份的后两位,用于后续区分平闰年
if (yearH>19)yearL+=100;//2000年之后,统一加上100
temp2=yearL+yearL/4;//平年,每年剩一天,每四年一个闰年,多剩一天
temp2=temp2%7;//对7取余,够7天填补一周
temp2=temp2+day+table_week[month-1]; //多余的天+日期+月份的修正(一月说明不需要修正,二月需要修正一月31天%7后,剩下的3天)
if (yearL%4==0&&month<3)temp2--;//补偿yearL+yearL/4中,由于正好能被4整除,多+的1天
if(temp2%7==0) return 7;//整除返回星期天
return(temp2%7);//返回星期几
}
//简化版 输入参数 年,月,日 unsigned char zeller_week(int y, int m, int d) { static int t[]={0,3,2,5,0,3,5,1,4,6,2,4}; y -= m<3; return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7; }
#include <stdio.h> int m_days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; bool is_leap_year(int year) { return year % (year % 100 ? 4 : 400) ? false : true; } int zeller_week(int y, int m, int d) /* 0 = Sunday */ { static int t[] = { 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 }; y -= m < 3; return (y + y / 4 - y / 100 + y / 400 + t[m - 1] + d) % 7; } void print_space(int fweek) { int cnt = fweek; for (int i = 0; i < cnt; i++) { printf("%s", " "); // 需要自己调节宽度 } } // 确定每月的天数 int get_m_days(int year, int month) { if (0 > month || 12 < month) return 0; static int days = m_days[month - 1]; if (2 == month && is_leap_year(year)) days++; return days; } //输出12个月份表 void print_calendar(int year, int month) { int days = get_m_days(year, month); // 调用函数,得到指定月天数 int one_day = zeller_week(year, month, 1); print_space(one_day); int week = one_day; int i = 1; while (i <= days) { printf("%8d", i); // 需要自己调节宽度 if (week == 6) /* 到一周结束,切换到下一行输出 */ { putchar(10); } i++; week = (week + 1) % 7; } } // 每个月第一天的星期数可以用蔡勒公式计算,之后每天不必重复使用蔡勒公式,用 // week = (week + 1) % 7 直接推算就可以了 int main(int argc, char *argv[]) { int y, m; printf("%s", "请输入年、月:> "); scanf("%d%*c%d", &y, &m); printf(" \n %s %s %s %s %s %s %s\n", "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"); print_calendar(y, m); // 产生 12 个月的日历循环 12 次即可 return 0; }