//p82New22.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; // 這也是亂來 dayOfWeek = REF_DAY_ONE; days = hehehe(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; int rryy, rrmm; // reference year/month 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; ans = haha(yyyy, mm, dd); return ans; } 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 p82New22.c D:\testc> a D:\testc> ****************/