原始迴圈法缺陷
while(!(year==0)){
if(year>0){ temp=isLeapYear(year-1)?366:365; year--; }
else { temp=-(isLeapYear(year)?366:365); year++; }
y+=temp;
}
- 效能差:跨度大時迴圈次數過多。
- 易出錯:負年處理、閏年邊界條件複雜。
優化公式
// 計算公元 1/1/1 至 year-1/12/31 總天數
long daysToYearStart(int year) {
if (year <= 0) year--; // 公元前無公元 0 年
long y = year - 1;
return 365L * y + y/4 - y/100 + y/400;
}
// 當年已過天數
int dayOfYear(int year, int month, int day) {
int[] md = {0,31,28,31,30,31,30,31,31,30,31,30,31};
if (isLeapYear(year)) md[2] = 29;
int sum = day;
for (int m = 1; m < month; m++) sum += md[m];
return sum;
}
// 兩日期差
long diffDays(int y1,int m1,int d1, int y2,int m2,int d2) {
return Math.abs( (daysToYearStart(y1)+dayOfYear(y1,m1,d1))
- (daysToYearStart(y2)+dayOfYear(y2,m2,d2)) );
}
優點
- O(1) 計算,無迴圈。
- 正確處理公元前(天文年編號:公元前 1 年 = year 0)。
- 易於單元測試驗證。