#include <stdio.h> #include <string.h> #include <stdlib.h>
#define BASEYEAR 2000 // base year #define BASEWN 6 // base week# (2000.1.1 is Saturday)
#define IS_LEAP(y) (!(y % 4) && (y % 100)) || !(y % 400) // is leap year?
long leaps(long sml, long big); int getweekn(long year, int mon, int day);
// #days from the first day of year(January.1) to month#.1 int mondays[2][13] = { // is not leap year {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}, // is leap year {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366} };
// get week# of year#.month#.day# // return week# on success, or not return -1 int getweekn(long year, int mon, int day) { long oyears; // year offset int odays; // days offset long oleaps = 0; // leap years int wkn; // the result week# int is; // is leap year? yes: is=1 or no: is=0
is = IS_LEAP(year);
// incorrect month# if (mon < 1 || mon > 12){ return -1; } // incorrect day# if ((day < 1) || (day > (mondays[is][mon] - mondays[is][mon - 1]))){ return -1; } // get wkn if (year >= BASEYEAR){ // here: off_year, offdays, lps are positive value oyears = (year - BASEYEAR) % 7; odays = mondays[is][mon - 1] + (day - 1); oleaps = leaps(BASEYEAR, year - 1); wkn = (oyears + odays + oleaps + BASEWN) % 7; } else{ // here: off_year, offdays, lps are negative value oyears = ((year + 1) - BASEYEAR) % 7; odays = mondays[is][mon - 1] - mondays[is][12] + (day - 1); oleaps = -1 * leaps(year + 1, BASEYEAR - 1); // convert negative value into positive wkn = ((oyears + odays + oleaps + BASEWN) % 7 + 7) % 7; }
return wkn; }
// get how many leap years from small year to big year // if big_year > small_year return lps, else return 0 long leaps(long sml, long big) { long lps = 0; // leap years long step; // small year increased by it long oset;
if (sml >= big){ return 0; }
for (step = 1; sml <= big; sml += step){ if (sml % 400 == 0){ lps++; oset = big - sml; lps += (oset / 4) - (oset / 100) + (oset / 400); break; } if (step == 1){ if (IS_LEAP(sml)){ step = 4; lps++; } continue; } if (sml % 100 != 0){ lps++; } }
return lps; }
int main(int argc, char *argv[]) { int wkday; long year; int mon; int cmondays; int i;
if (argc != 3){ printf("usage: %s year month\n", argv[0]); return 0; } year = atoi(argv[1]); mon = atoi(argv[2]); if (mon < 1 || mon > 12){ printf("Bad agument: month should between 1 and 12\n"); return 0; }
wkday = getweekn(year, mon, 1); cmondays = mondays[IS_LEAP(year)][mon] - mondays[IS_LEAP(year)][mon - 1];
printf("\n\t\t===================== Calendar =====================\n"); printf("\t\t date: %ld.%d\n\n", year, mon); printf("\t\tSUN\tMON\tTUE\tWEN\tTHU\tFRI\tSAT\n\t\t"); for (i = 0; i < wkday; i++){ printf(" \t"); } for (i = 0; i < cmondays; i++){ if ((i != 0) && ((i + wkday) % 7 == 0)){ printf("\n\t\t"); } printf("%2d \t", i + 1); } printf("\n\n");
return 0; }
|