# 一个C程序例子:打印指定日期所属月的月历

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

int days[6][7];
int mdays[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int mdays2[] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

#define is_leap_year(y)      ((!((y) % 4) && ((y) % 100)) || (!((y) % 400)))
#define max_mdays(m, y)      (is_leap_year(y) ? mdays2[m] : mdays[m])

// 计算指定日期与当前日期相差天数
int diff_days(int y1, int m1, int d1, int y2, int m2, int d2)
{
int d = 0;
int md = max_mdays(m1, y1);

while ((y1 != y2) || (m1 != m2) || (d1 != d2))
{
d++;
d1++;
if (d1 > md)
{
d1 = 1;
m1++;
if (m1 >= 12)
{
m1 = 0;
y1++;
}
md = max_mdays(m1, y1);
}
}

return d;
}

int get_wday(int y, int m, int d)
{
struct tm tm;
time_t t;
int cy, cm, cd, cw;
int dd, w, f = 0;

time(&t);
tm = *localtime(&t);

cy = tm.tm_year + 1900;
cm = tm.tm_mon;
cd = tm.tm_mday;
cw = tm.tm_wday;

if (cy < y)
{
dd = diff_days(cy, cm, cd, y, m, d);
f = 1;
}
else if (cy > y)
{
dd = diff_days(y, m, d, cy, cm, cd);
}
else
{
if (cm < m)
{
dd = diff_days(cy, cm, cd, y, m, d);
f = 1;
}
else if (cm > m)
{
dd = diff_days(y, m, d, cy, cm, cd);
}
else
{
if (cd < d)
{
dd = diff_days(cy, cm, cd, y, m, d);
f = 1;
}
else if (cd > d)
{
dd = diff_days(y, m, d, cy, cm, cd);
}
else
{
dd = 0;
}
}
}

// 计算指定日期是星期几
w = f ? (cw + (dd % 7)) : (cw - (dd % 7)) ;
if (w < 0)
{
w += 7;
}

// 计算指定日期所属月的第一天是星期几
w = (w - ((d - 1) % 7));
if (w < 0)
{
w += 7;
}

return w;
}

int main()
{
int year, mon, day;
int i, j, d, w, md;

printf("请输入日期： ");
scanf("%d %d %d", &year, &mon, &day);

if (((mon < 1) || (mon > 12))
|| ((day < 0) || (day > mdays[mon - 1])))
{
printf("输入错误! [1 <= 月  <= 12] [1 <= 日 <= 31]/n");
return -1;
}

w = get_wday(year, mon - 1, day);
md = max_mdays(mon - 1, year);
d = 1;

while (d <= md)
{
i = w / 7;
j = w % 7;

days[i][j] = d++;
w++;
}

printf("/n 日期： %d 年 %d 月 %d日/n", year, mon, day);
printf("==============================/n");
printf(" %2s  %2s  %2s  %2s  %2s  %2s  %2s/n", "日", "一", "二", "三", "四", "五", "六");
for (i = 0, d = 0; i < 6; i++)
{
for (j = 0; j < 7; j++)
{
if (days[i][j])
{
d++;
(d == day) ? printf("[%2d]", d) : printf(" %2d ", d);
}
else
{
printf("%-4s", "");
}
}
printf("/n");
}
printf("==============================/n");

system("pause");

return 0;
}