//p82New.c -- another reference program for Lab08 Calendar // 算出 yyyy/mm/01 離 0001/01/01 有幾天 // 至於從 1752/10/01 算到某天有幾天一樣簡單吧? // 以及中國西元曆 1912/01/01 算到某天有幾天自己想 // 注意此範例故意寫成輸入 year month // 與原來習題規定不同喔! #include #include #include #define C_USA 0 #define C_CN 2 int yyyy, mm, dd, what, country; // year, month, day long hehehe(int, int, int yyyy), days; long haha(int, int, int yyyy); int dayOfWeek; // 參考點是星期幾? const int REF_DAY_ONE = 6; // 注意 0001/01/01 是週六 const int REF_DAY_TWO = 0; // for C_USA 1752/10/01 Sunday const int REF_DAY_THREE = 1; // for C_CN 1912/01/01 Monday char buf[999]; // 不信你會打那麼多字 ? char dName[ ][66]={"Sunday", "星期一", "Tuesday", "Wed", "週四", "Friday", "Saturday週六" }; int main( ) { int rryy, rrmm; // 參考點 int i, k; country = C_USA; // assume USA; also try C_CN for( ;; ) { printf("Year month day(年 月 日): "); // 注意現在是 年 月 fgets(buf, sizeof(buf), stdin); what = sscanf(buf, "%d %d %d", &yyyy, &mm, &dd); if(yyyy <= 0) break; // 不玩了 //if(what !=2 ) continue; // 必須兩個數 if(mm > 12) continue; // 月 <= 12 啊 if(mm <=0 ) continue; // 這也是亂來 days = hehehe(yyyy, mm, dd); dayOfWeek = REF_DAY_ONE; rryy = 1752; rrmm = 9; // for C_USA if(country==C_CN) { rryy=1911; rrmm =13; } if((yyyy > rryy) || ((yyyy==rryy) && (mm >= rrmm))) { dayOfWeek = REF_DAY_TWO; if(country==C_CN) dayOfWeek = REF_DAY_THREE; days = haha(yyyy, mm, dd); } //printf("===%d\n", dayOfWeek); printf("From 0001/01/01 to %4.4d/%02d/%02d:", yyyy, mm, dd); printf(" Total 過 %ld weeks + %ld days.", days/7, days%7); // long 喔 dayOfWeek = (int)(dayOfWeek+ (days%7)) % 7; /// printf("\n %4.4d/%02d/%02d is %s\n", yyyy, mm, dd, dName[dayOfWeek]); }// for printf("Hit ENTER key..."); getchar( ); // waiting he to hit ENTER return 0; } int isLeap(int y) { int ans = 0, ref=1752; // 調整點 if(country == C_CN) ref=1911; if( y <= ref ) return (y%4)==0; /// 舊式算法 (凱薩曆) if( (y % 400) == 0 ) return 1; if( (y % 100) == 0 ) return 0; if( (y % 4) == 0 ) return 1; return 0; // todo .. return ans;; } int dayTbl[ ] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; // July..Dec long hehehe(int year, int month, int dd) { // 舊式算法 (凱薩曆) //int dd = 1; // 1/1/1 算到 year/month/01 幾天 long ans = 0; int i, k; ans = 365 * (year -1); for(i=1; i< year; i++) if( isLeap(i) ) ++ans; // 閏年多一天 for(i=1; i< month; ++i) ans += dayTbl[i]; if( (month > 2) && isLeap(year) ) ++ans; //今年閏年 ans = ans + dd -1; // 這個月 1 日 (dd == 1) return ans; }// long ccc(int year, int month, int dd) { // for C_CN only long ans = 0; int i, k; // 1912/01/01 ---> ans = 365 * (year -1912); for(i=1912; i< year; i++) if( isLeap(i) ) ++ans; for(i=1; i< month; ++i) ans += dayTbl[i]; if( (month > 2) && isLeap(year) ) ++ans; //今年閏年 ans = ans + dd -1; // 這個月 1 日 (dd == 1) return ans; } long haha(int year, int month, int dd) { // 新式算法 (儒略曆) //int dd = 1; // 1752/10/1 算到 year/month/01 幾天 long ans = 0; int i, k; if(country==C_CN) return ccc(year, month, dd); if(country==C_USA && year == 1752 && month == 9) { dayOfWeek = 2; // 1752/09/01 is Tuesday ans = dd - 1; if(dd >= 14) ans = ans - 11; // 9/3 == 就是 9/14 THR return ans; } if(country==C_USA && year == 1752) { // 這年比較特別 ! for(i=10; i< month; ++i) ans += dayTbl[i]; ans = ans + dd -1; return ans; } ans = 31 + 30 + 31; ans += 365 * (year -1753); for(i=1753; i< year; i++) if( isLeap(i) ) ++ans; // 閏年多一天 for(i=1; i< month; ++i) ans += dayTbl[i]; if( (month > 2) && isLeap(year) ) ++ans; //今年閏年 ans = ans + dd -1; // 這個月 1 日 (dd == 1) return ans; }// /*************** D:\testc> path c:\Dec-Cpp\bin;%path% D:\testc> gcc p82New.c D:\testc> a Year month day(年 月 日): 1912 1 1 From 0001/01/01 to 1912/01/01: Total 過 8309 weeks + 1 days. 1912/01/01 is 星期一 Year month day(年 月 日): 1752 10 1 From 0001/01/01 to 1752/10/01: Total 過 0 weeks + 0 days. 1752/10/01 is Sunday Year month day(年 月 日): 1752 9 30 From 0001/01/01 to 1752/09/30: Total 過 2 weeks + 4 days. 1752/09/30 is Saturday週六 Year month day(年 月 日): 1752 9 23 From 0001/01/01 to 1752/09/23: Total 過 1 weeks + 4 days. 1752/09/23 is Saturday週六 Year month day(年 月 日): 1752 9 16 From 0001/01/01 to 1752/09/16: Total 過 0 weeks + 4 days. Year month day(年 月 日): 1752 9 1 From 0001/01/01 to 1752/09/01: Total 過 0 weeks + 0 days. 1752/09/01 is Tuesday Year month day(年 月 日): 1752 9 2 From 0001/01/01 to 1752/09/02: Total 過 0 weeks + 1 days. 1752/09/02 is Wed Year month day(年 月 日): 1752 9 14 From 0001/01/01 to 1752/09/14: Total 過 0 weeks + 2 days. 1752/09/14 is 週四 Year month day(年 月 日): 1 1 1 From 0001/01/01 to 0001/01/01: Total 過 0 weeks + 0 days. 0001/01/01 is Saturday週六 Year month day(年 月 日): -1 Hit ENTER key... D:\testc> ****************/