/*
 *File:PrintCalendar.c
 *---------------------
 *用户输入年份(1900年以后),自动打印出此年的日历
 */
 
#include<stdio.h>
#define Sunday 0 
#define Monday 1
#define Tuesday 2
#define Wednesday 3
#define Thursday 4
#define Friday 5
#define Saturday 6
/*Function Prototypes*/
void GiveInstructions(void);
int GetYearFromUser(void);
void PrintCalendar(int year);
void PrintCalendarMonth(int month, int year);
void IndentFirstLine(int weekday);
int MonthDays(int month, int year);
int FirstDayOfMonth(int month, int year);
bool IsLeapYear(int year);
/*Main Program*/
main()
{
      int year;
     
      GiveInstructions();
      year = GetYearFromUser();
      PrintCalendar(year);
      
}
/* GiveInstruction(void)给出用户此程序的功能.*/
void GiveInstructions(void)
{
     printf("This program displays a calendar for a full year.\n");
     printf("The year must be after 1900.\n");
}
/* year = GetYearFromUser()让用户输入年份.*/
int GetYearFromUser()
{
    int year;
    
    while(1 > 0) {
            printf("Which year?\n");
            scanf("%d", &year);
            if(year >= 1900) return(year);
            printf("The year must be at least 1900.\n");
    }
}
/* PrintCalendar(year) 调用PrintCalendarMonth(month, year)来输出一整年的日历*/
void PrintCalendar(int year)
{
     int month;
     
     for(month = 1; month <= 12; month++) {
               PrintCalendarMonth(month, year);
               printf("\n");
     }
}
/* printCalendarMonth(month, year) 用来输出给定年的给定月的日历,weekday是取值在1~7的整型变量*/
void PrintCalendarMonth(int month, int year)
{
     int weekday, nDays, day;
    
     printf("      %s     %d\n", month, year);
     printf("Su Mo Tu We Th Fr Sa\n");
     nDays = MonthDays(month, year);
     weekday = FirstDayOfMonth(month, year);
     IndentFirstLine(weekday);
     for(day = 1; day <= nDays; day++) {
               printf("%2d", day);
               if(weekday = Saturday) printf("\n");
               weekday = (weekday + 1) % 7;
     }
     if(weekday != Sunday) printf("\n");
}
/* IndentFirstLine(weekday) 使每个月的一号显示在正确的位置*/
void IndentFirstLine(int weekday) 
{
     int i;
     
     for(i = 0; i < weekday; i++) {
           printf("  ");
     }
}
/* MonthDays(month, year) 求出给定年的某月的天数*/
int MonthDays(int month, int year)
{
    switch(month) {
                  case 2:
                       if(IsLeapYear(year)) return(29);
                       return(28);
                  case 4: case 6: case 9: case 11:
                       return(30);
                  default:
                          return(31);
    }
}        
/* FirstDayOfMonth(month, year)求出此年此月的一号是星期几(根据1900年1月1
日是星期一来求)*/
int FirstDayOfMonth(int month, int year)
{
    int weekday, i;
    weekday = Monday;
    
    for(i = 1900; i < year; i++) {
          weekday = (weekday + 365) % 7;
          if(IsLeapYear(i)) weekday = (weekday + 1) % 7;
    }
    for(i = 1; i < month; i++) {
          weekday = (weekday + MonthDays(i, year)) % 7;
    }
    return(weekday);
}
/* IsLeapYear(year) 判断十分为闰年*/
bool IsLeapYear(int year) 
{
     return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
}
                                    

 
											





 
	    