2016-09-06 626 views
2

我想計算兩個日期之間的天數。常見問題。JS - 計算考慮閏年的兩個日期之間的天數

對於爲例:

var d0 = new Date("2016-02-27"); 
var d1 = new Date("2017-08-25"); 

Manypeople建議使用劃時代的區別:

var res = (d1 - d0)/1000/60/60/24; 
// res = 545 days 

但我懷疑,所以我寫了一個天真的功能:

function days(d0, d1) 
{ 
    var d = new Date(d0); 
    var n = 0; 
    while(d < d1) 
    { 
     d.setDate(d.getDate() + 1); 
     n++; 
    } 
    return n; 
} 

此功能與時代差異本質上輸出相同的結果,但不是與我的具體例子。可能因爲2016年是閏年。

res = days(d0, d1); 
// res = 546 days 

任何想法爲什麼?

+0

這是一個很好理解和記錄的主題,一些輕的谷歌搜索將揭示大量的信息。 – Yoda

+0

一些輕的谷歌搜索結果顯示,人們只是使用時代差異堅持使用,而不會與日期地獄搞得太多。 –

+0

這很奇怪,但它不是導致差異的閏日。如果您嘗試2016年2月27日至2016年1月1日,一切都是正確的。 – Fels

回答

1

經過測試,看起來循環停止在2017-08-26而不是2017-08-25

當您打印的d0d1價值,這裏是結果:

D0:星期六2016年2月27日01:00:00 GMT + 0100(中歐標準時間)

D1 :2017年8月25日星期二02:00:00 GMT + 0200(中歐日照時間)

正如您所看到的,兩個日期之間有一個小時的轉換,所以當循環索引達到2017年8月25日,這種轉變仍然存在並使「低於」操作爲真,它應該是假的。

請務必在使用前規範日期。

0

它與閏年沒有任何關係,而是因爲你正在合併UTC和當地時間。

new Date("2016-02-27") // JS will interpret this input as UTC due to the hyphens 

d.setDate(d.getDate() + 1); // these get/set functions work with the LOCAL date 

這兩個都需要在同一個環境下工作。由於您無法確定本地時區是否會經歷夏令時,或者您將跨過DST過渡,因此使用UTC工作比在當地工作時更安全。

簡單地改變你的功能,使用方法:

d.setUTCDate(d.getUTCDate() + 1); 

另外,可以考慮像moment.js一個圖書館,讓這些事情都已經解決。

moment("2017-08-25").diff("2016-02-27", "days") // 545 

只要輸入解釋爲UTC,那麼您顯示的基於時代的方法也是正確的。