2016-09-06 8 views
2

Я хочу рассчитать количество дней между двумя датами. Общая проблема.JS - Рассчитать количество дней между 2 датами с учетом високосного года

Для Exemple:

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-02-27 до 2016-03-01, все будет правильно. – Fels

ответ

1

После тестирования, кажется, что останов петли на 2017-08-26, а не 2017-08-25.

При печати значение d0 и d1, вот результат:

d0: Сб 27 февраля 2016 1:00:00 GMT + 0100 (Центральная Европа Standard Time)

d1 : Пт. 25 авг 2017 02:00:00 GMT + 0200 (Центральноевропейское летнее время)

Как вы можете видеть, между двумя датами существует одночасовая смена, поэтому, когда индекс петли достигает 25 августа 2017 года, этот сдвиг все еще существует и делает операцию «ниже» истиной, где она должна быть ложной.

Обязательно нормализуйте даты, прежде чем использовать их.

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 

Оба они должны работать в одном контексте. Поскольку вы не можете быть уверены, что местный часовой пояс будет работать на летнее время или нет, или если вы перейдете на переход на летнее время, работа в формате UTC будет гораздо более безопасной, чем в локальное время.

Просто измените функцию, чтобы использовать:

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

В качестве альтернативы рассмотрим библиотеку как moment.js, где эти вещи уже разработаны.

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

Подходящий эпохальный подход также является правильным, если входы интерпретируются как UTC.