2009年6月15日 星期一

兩天天數差 與 週數計算

//===============================================================
// 20090614 知識 +
// http://tw.knowledge.yahoo.com/question/question?qid=1609061406632
// 發問者 :(↙小貓頭﹌MOMO↗ ) http://tw.knowledge.yahoo.com/my/my?show=AD01407519
//===============================================================

這是小程式, 所以就分別用 C 和 C++ 寫了一次; 要注意得是 fflush(stdin) 在C++中是無法清除錯誤輸入的, 所以在C++就用了其它的方法來處理... 而若程式有需要考慮編譯的相容性時, 一般是建議不要使用未有標準定義的fflush(stdin) .

(A) C 程式

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

// 取得天數(回傳值), 並回傳星期幾(*week) 與 當年第幾週(*yw)
int GetDays(int year, int month, int day, int *week, int *yw )
{
int m[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if ((year%4==0 && year%100!=0) || year%400==0) m[1]=29; // 閏年2月
if (year<1 || month<1 || month>12 || day<1 || day>m[month-1]) return -1;
int y = year-1;
int d = y*365+y/4-y/100+y/400; // d: 年前總天數
int i, dy=day;
for(i=0; i<month-1; i++) dy+= m[i]; // dy: 當年天數
*week = (d+dy)%7; // 星期
*yw = (dy+d%7)/7+1; // 第幾週
return (d+dy); // 統計天數
}
// 主程式 ====
int main()
{
char *week[]= { "日", "一", "二", "三", "四", "五", "六" };
int y1, m1, d1, da1, w1, yw1;
int y2, m2, d2, da2, w2, yw2;
while(!fflush(stdin))
{
printf( "請輸入第一個日期(西元年﹑月﹑日,請以空白相隔): ");
if (scanf("%d %d %d", &y1, &m1, &d1)==3 &&
(da1 = GetDays(y1, m1, d1, &w1, &yw1))>0) break;
printf( "日期輸入錯誤!!\n重新");
}
while(!fflush(stdin))
{
printf( "請輸入第二個日期(西元年﹑月﹑日,請以空白相隔): ");
if (scanf("%d %d %d", &y2, &m2, &d2)==3 &&
(da2 = GetDays(y2, m2, d2, &w2, &yw2))>0) break;
printf( "日期輸入錯誤!!\n重新");
}
int days = (da1>da2)? da1-da2: da2-da1; // 計算兩天所差天數
printf( "\n第一個日期為 星期%s 為當年的第 %d週", week[w1], yw1);
printf( "\n第二個日期為 星期%s 為當年的第 %d週", week[w2], yw2);
printf ( "\n兩個日期相差 %d天 間隔 %d週", days, days/7 );
if (days%7==0) printf( "整\n\n");
else printf ("又 %d天\n\n", days%7);

system("pause"); // 暫停
return 0;
}
//==============================================================


(B) C++ 程式

#include <iostream>
#include <limits> // 為了用 numeric_limits (clearInput函式用)
using namespace std;

// 取得天數(回傳值), 並回傳星期幾(*week) 與 當年第幾週(*yw)
int GetDays(int year, int month, int day, int *week, int *yw )
{
int m[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if ((year%4==0 && year%100!=0) || year%400==0) m[1]=29; // 閏年2月
if (year<1 || month<1 || month>12 || day<1 || day>m[month-1]) return -1;
int y = year-1;
int d = y*365+y/4-y/100+y/400; // d: 年前總天數
int dy=day;
for(int i=0; i<month-1; i++) dy+= m[i]; // dy: 當年天數
*week = (d+dy)%7; // 星期
*yw = (dy+d%7)/7+1; // 第幾週
return (d+dy); // 統計天數
}
// 淨空錯誤輸入 ---
void clearInput()
{
cin.clear();
cin.ignore( numeric_limits<streamsize>::max(), '\n' );
}
// 主程式 ====
int main()
{
char *week[]= { "日", "一", "二", "三", "四", "五", "六" };
int y1, m1, d1, da1, w1, yw1;
int y2, m2, d2, da2, w2, yw2;
for(y1=m1=d1=0; true; clearInput(), y1=m1=d1=0)
{
cout<< "請輸入第一個日期(西元年﹑月﹑日,請以空白相隔): ";
cin >> y1 >> m1 >> d1;
if ((da1 = GetDays(y1, m1, d1, &w1, &yw1))>0) break;
cout<< "日期輸入錯誤!!"<< endl << "重新";
}
for(y2=m2=d2=0; true; clearInput(), y2=m2=d2=0)
{
cout<< "請輸入第二個日期(西元年﹑月﹑日,請以空白相隔): ";
cin >> y2 >> m2 >> d2;
if ((da2 = GetDays(y2, m2, d2, &w2, &yw2))>0) break;
cout<< "日期輸入錯誤!!"<< endl << "重新";
}
int days = (da1>da2)? da1-da2: da2-da1; // 計算兩天所差天數
cout<< endl << "第一個日期為 星期" << week[w1] << " 為當年的第 "<< yw1 << "週";
cout<< endl << "第二個日期為 星期" << week[w2] << " 為當年的第 "<< yw2 << "週";
cout<< endl << "兩個日期相差 " << days << "天 間隔 " << (days/7) << "週";
if (days%7==0) cout<< "整" << endl << endl;
else cout<< "又 "<< (days%7) << "天" << endl << endl;

system("pause"); // 暫停
return 0;
}
//==============================================================


【執行結果】 :
請輸入第一個日期(西元年﹑月﹑日,請以空白相隔): 1980 5 10
請輸入第二個日期(西元年﹑月﹑日,請以空白相隔): 2009 6 16

第一個日期為 星期六 為當年的第 19週
第二個日期為 星期二 為當年的第 25週
兩個日期相差 10629天 間隔 1518週又 3天

沒有留言:

張貼留言