Как узнать количество дней между двумя датами в JavaScript? - PullRequest
353 голосов
/ 12 февраля 2009

Как узнать количество дней между двумя датами в JavaScript? Например, в полях ввода указаны две даты:

<input id="first" value="1/1/2000"/>
<input id="second" value="1/1/2001"/>

<script>
  alert(datediff("day", first, second)); // what goes here?
</script>

Ответы [ 35 ]

371 голосов
/ 12 февраля 2009

Вот быстрая и грязная реализация datediff, как подтверждение концепции для решения проблемы, представленной в вопросе. Он основан на том факте, что вы можете получить прошедшие миллисекунды между двумя датами, вычитая их, что приводит их к значению их примитивного числа (миллисекунды с начала 1970 года).

// new Date("dateString") is browser-dependent and discouraged, so we'll write
// a simple parse function for U.S. date format (which does no error checking)
function parseDate(str) {
    var mdy = str.split('/');
    return new Date(mdy[2], mdy[0]-1, mdy[1]);
}

function datediff(first, second) {
    // Take the difference between the dates and divide by milliseconds per day.
    // Round to nearest whole number to deal with DST.
    return Math.round((second-first)/(1000*60*60*24));
}

alert(datediff(parseDate(first.value), parseDate(second.value)));
<input id="first" value="1/1/2000"/>
<input id="second" value="1/1/2001"/>

Вы должны знать, что «нормальные» API-интерфейсы Date (без «UTC» в названии) работают в локальном часовом поясе браузера пользователя, поэтому в целом вы можете столкнуться с проблемами, если ваш пользователь находится в часовом поясе, который вы не ожидайте, и ваш код будет иметь дело с переходами на летнее время. Вам следует внимательно прочитать документацию по объекту Date и его методам, а для чего-либо более сложного настоятельно рекомендуем использовать библиотеку, которая предлагает более безопасные и мощные API для манипулирования датами.

Также, в целях иллюстрации, фрагмент использует именованный доступ к window объекту для краткости, но в производстве вы должны использовать стандартизированные API, такие как getElementById или более вероятно, некоторые рамки пользовательского интерфейса.

193 голосов
/ 29 июня 2012

На момент написания статьи только один из других ответов правильно обрабатывал переходы DST (летнее время). Вот результаты для системы, расположенной в Калифорнии:

                                        1/1/2013- 3/10/2013- 11/3/2013-
User       Formula                      2/1/2013  3/11/2013  11/4/2013  Result
---------  ---------------------------  --------  ---------  ---------  ---------
Miles                   (d2 - d1) / N   31        0.9583333  1.0416666  Incorrect
some         Math.floor((d2 - d1) / N)  31        0          1          Incorrect
fuentesjr    Math.round((d2 - d1) / N)  31        1          1          Correct
toloco     Math.ceiling((d2 - d1) / N)  31        1          2          Incorrect

N = 86400000

Хотя Math.round возвращает правильные результаты, я думаю, что это несколько неуклюже. Вместо этого, явно учитывая изменения в смещении UTC, когда начинается или заканчивается летнее время, мы можем использовать точную арифметику:

function treatAsUTC(date) {
    var result = new Date(date);
    result.setMinutes(result.getMinutes() - result.getTimezoneOffset());
    return result;
}

function daysBetween(startDate, endDate) {
    var millisecondsPerDay = 24 * 60 * 60 * 1000;
    return (treatAsUTC(endDate) - treatAsUTC(startDate)) / millisecondsPerDay;
}

alert(daysBetween($('#first').val(), $('#second').val()));

Объяснение

Вычисление даты в JavaScript сложно, потому что Date объекты хранят время внутри UTC, а не по местному времени. Например, 3/10/2013 12:00 по тихоокеанскому стандартному времени (UTC-08: 00) хранится как 3/10/2013 8:00 по UTC и 11.03.2013 в 12:00 по тихоокеанскому летнему времени ( UTC-07: 00) хранится как 11.03.2013 7:00 UTC. В этот день с полуночи до полуночи по местному времени в UTC только 23 часа!

Хотя день по местному времени может иметь больше или меньше 24 часов, день в UTC всегда составляет ровно 24 часа. 1 Показанный выше метод daysBetween использует этот факт при первом вызове treatAsUTC для корректировки местного времени до полуночи UTC перед вычитанием и делением.

1. JavaScript игнорирует дополнительные секунды.

107 голосов
/ 13 февраля 2009

Самый простой способ получить разницу между двумя датами:

var diff =  Math.floor(( Date.parse(str2) - Date.parse(str1) ) / 86400000); 

Вы получаете разницу дней (или NaN, если один или оба не могут быть проанализированы). Дата разбора дала результат в миллисекундах, и чтобы получить его по дням, нужно разделить его на 24 * 60 * 60 *1000* 1004 *

Если вы хотите, чтобы оно делилось на дни, часы, минуты, секунды и миллисекунды:

function dateDiff( str1, str2 ) {
    var diff = Date.parse( str2 ) - Date.parse( str1 ); 
    return isNaN( diff ) ? NaN : {
        diff : diff,
        ms : Math.floor( diff            % 1000 ),
        s  : Math.floor( diff /     1000 %   60 ),
        m  : Math.floor( diff /    60000 %   60 ),
        h  : Math.floor( diff /  3600000 %   24 ),
        d  : Math.floor( diff / 86400000        )
    };
}

Вот моя переработанная версия Джеймса:

function mydiff(date1,date2,interval) {
    var second=1000, minute=second*60, hour=minute*60, day=hour*24, week=day*7;
    date1 = new Date(date1);
    date2 = new Date(date2);
    var timediff = date2 - date1;
    if (isNaN(timediff)) return NaN;
    switch (interval) {
        case "years": return date2.getFullYear() - date1.getFullYear();
        case "months": return (
            ( date2.getFullYear() * 12 + date2.getMonth() )
            -
            ( date1.getFullYear() * 12 + date1.getMonth() )
        );
        case "weeks"  : return Math.floor(timediff / week);
        case "days"   : return Math.floor(timediff / day); 
        case "hours"  : return Math.floor(timediff / hour); 
        case "minutes": return Math.floor(timediff / minute);
        case "seconds": return Math.floor(timediff / second);
        default: return undefined;
    }
}
82 голосов
/ 21 августа 2013

Я рекомендую использовать библиотеку moment.js (http://momentjs.com/docs/#/displaying/difference/).. Она правильно обрабатывает переход на летнее время и в целом с ней приятно работать.

Пример:

var start = moment("2013-11-03");
var end = moment("2013-11-04");
end.diff(start, "days")
1
40 голосов
/ 12 февраля 2009

Я бы пошел дальше и взял бы эту маленькую утилиту , и в ней вы найдете функции для этого для вас. Вот краткий пример:

        <script type="text/javascript" src="date.js"></script>
        <script type="text/javascript">
            var minutes = 1000*60;
            var hours = minutes*60;
            var days = hours*24;

            var foo_date1 = getDateFromFormat("02/10/2009", "M/d/y");
            var foo_date2 = getDateFromFormat("02/12/2009", "M/d/y");

            var diff_date = Math.round((foo_date2 - foo_date1)/days);
            alert("Diff date is: " + diff_date );
        </script>
14 голосов
/ 08 ноября 2017
const startDate = '2017-11-08';
const endDate   = '2017-10-01';
const timeDiff  = (new Date(startDate)) - (new Date(endDate));
const days      = timeDiff / (1000 * 60 * 60 * 24)
  1. Установить дату начала
  2. Установить дату окончания
  3. Рассчитать разницу
  4. Преобразование миллисекунд в дни
12 голосов
/ 30 апреля 2015

Использование Moment.js

var future = moment('05/02/2015');
var start = moment('04/23/2015');
var d = future.diff(start, 'days'); // 9
console.log(d);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment-with-locales.min.js"></script>
10 голосов
/ 20 ноября 2013

Значения даты в JS являются значениями даты и времени.

Итак, прямые вычисления даты противоречивы:

(2013-11-05 00:00:00) - (2013-11-04 10:10:10) < 1 day

например, нам нужно преобразовать 2-ю дату:

(2013-11-05 00:00:00) - (2013-11-04 00:00:00) = 1 day

метод можно обрезать мельницы в обе даты:

var date1 = new Date('2013/11/04 00:00:00');
var date2 = new Date('2013/11/04 10:10:10'); //less than 1
var start = Math.floor(date1.getTime() / (3600 * 24 * 1000)); //days as integer from..
var end = Math.floor(date2.getTime() / (3600 * 24 * 1000)); //days as integer from..
var daysDiff = end - start; // exact dates
console.log(daysDiff);

date2 = new Date('2013/11/05 00:00:00'); //1

var start = Math.floor(date1.getTime() / (3600 * 24 * 1000)); //days as integer from..
var end = Math.floor(date2.getTime() / (3600 * 24 * 1000)); //days as integer from..
var daysDiff = end - start; // exact dates
console.log(daysDiff);
9 голосов
/ 30 апреля 2015

Лучше избавиться от DST, Math.ceil, Math.floor и т. Д., Используя время UTC:

var firstDate = Date.UTC(2015,01,2);
var secondDate = Date.UTC(2015,04,22);
var diff = Math.abs((firstDate.valueOf() 
    - secondDate.valueOf())/(24*60*60*1000));

Этот пример дает разницу в 109 дней. 24*60*60*1000 - это один день в миллисекундах.

9 голосов
/ 11 января 2016

Для расчета дней между 2 указанными датами вы можете использовать следующий код. Даты, которые я здесь использую, - 01 января 2016 года и 31 декабря 2016 года

var day_start = new Date("Jan 01 2016");
var day_end = new Date("Dec 31 2016");
var total_days = (day_end - day_start) / (1000 * 60 * 60 * 24);
document.getElementById("demo").innerHTML = Math.round(total_days);
<h3>DAYS BETWEEN GIVEN DATES</h3>
<p id="demo"></p>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...