Как узнать количество дней между двумя датами в JavaScript?


403

Как узнать количество дней между двумя датами в 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>

5
В 99% случаев, когда пользователь спрашивает «количество дней между двумя датами», он не понимает, что он пытается сравнить яблоки с грушами. Проблема становится настолько простой, если спросить «Сколько ДАТ ДА в ДИАПАЗОНЕ ДАТ?» Или Сколько квадратов мне нужно пересечь в календаре. Это оставляет время и проблемы с переходом на летнее время и т. Д. И т. Д. Путаница подразумевается для нас из-за структуры данных datetime, которая является чистой чепухой. Нет такой вещи, как дата, время, есть дата и есть время, два совершенно разных объекта как по природе, так и по поведению
Михаил Шишков

Для функции, которая разбивает разницу на (целые) единицы времени, используйте ответ по адресу stackoverflow.com/a/53092438/3787376 .
Эдвард

Я чувствую, что этот вопрос должен быть удален или хотя бы помечен как «избегать», так как большинство ответов либо неверны, либо зависят от различных библиотек.
RobG

Ответы:


409

Вот быстрое и грязное внедрение 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 , или, более вероятно, некоторую инфраструктуру пользовательского интерфейса.


2
Я думаю, что Math.trunc () является более подходящим. На всякий случай, если кто-то использует более точные объекты Date (например, часы, минуты и секунды)
Jin Wang

21
Поскольку ответ помечен как правильный и получил наибольшее количество голосов (на данный момент), стоит отметить, что этот ответ неправильно обрабатывает переход на летнее время. Смотрите ответ Майкла Лю вместо этого.
osullic

Что именно делает parseDate?
Мухаммед Кермани

2
@ osullic - этот ответ обрабатывает переход на летнее время с помощью Math.round , однако он ожидает, что будут передаваться только строки даты, а не дата и время.
RobG

2
Просто помните, что в этом примере дата указана в формате США, т.е. ММ / ДД / ГГГГ. Если вам нужна версия для Великобритании, вам нужно изменить parseDateметод на:return new Date(mdy[2], mdy[1], mdy[0]-1);
Viqas

207

На момент написания статьи только один из других ответов правильно обрабатывал переходы 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, когда начинается или заканчивается DST, мы можем использовать точную арифметику:

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 часа. 1daysBetween способ , показанный выше , использует этот факт первого вызова , treatAsUTCчтобы настроить как местное время до полуночи UTC до вычитания и деления.

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


2
Нет необходимости использовать UTC, просто установить местное время на полночь (или одинаковое значение для обеих дат). Дробный день, введенный переходом на летнее время, составляет максимум ± 0,04 (а в некоторых местах меньше), поэтому он округляется с помощью Math.round . ;-) Полагаться на конструктор Date для разбора строк не очень хорошая идея. Если вы действительно хотите использовать значения UTC, проанализируйте строки, используя Date.UTC(...)в первую очередь.
RobG

2
@RobG: Как я сказал в своем ответе: «Хотя Math.round возвращает правильные результаты, я думаю, что это несколько неуклюже. Вместо этого, явно учитывая изменения в смещении UTC, когда начинается или заканчивается летнее время, мы можем использовать точную арифметику».
Майкл Лю

На самом деле, времена, которые вы представляли как «неправильные», технически верны. Вы не меняете DateTimes на UTC ... вы просто меняете время каждого DateTime, чтобы получить искусственное целое число. Округление не "неуклюжее" ... это совершенно правильный подход, потому что в любом случае это то, что вы делаете в своей голове: вы округляете часть времени (часы, минуты, секунды) и просто пытаетесь получить целое номер дня
JDB до сих пор помнит Монику

116

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

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

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

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

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;
    }
}

2
Плохой ответ Math.floor () потеряет вас в тот день, когда часы перейдут на летнее время. Math.round () даст правильный ответ в большинстве ситуаций, но есть и лучшие варианты и в другом ответе.
Фил Б

101

Я рекомендую использовать библиотеку 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

10
Так же, как предупреждение, хотя момент - это здорово, это довольно большая зависимость
Джейсон Аксельсон

Так и должно быть, end.diff(start,"days")хотя написанный код будет работать, потому что дата начала после даты окончания!
gordon613

40

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

        <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>

28
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. Конвертировать миллисекунды в дни

Обновление: я знаю, что это не является частью ваших вопросов, но в целом я бы не рекомендовал делать какие-либо вычисления или манипуляции с датами в vanilla JavaScript, а использовать для этого библиотеку типа date-fns или moment.js из-за множества крайних случаев.


5
Я ценю такие ответы: короткие, простые и не требующие случайных зависимостей! Приветствия.
daCoda

2
Это только я timeDiffвернулся в минус? Не должно timeDiffбыть (new Date(endDate)) - (new Date(startDate));?
Feyisayo Sonubi

@ feyisayo-sonubi зависит от того, в каком порядке вы указали дату начала и окончания. В этом примере(new Date('2017-11-08')) - (new Date('2017-10-01')) // 3283200000
marcobiedermann

const timeDiff = +(new Date(start)) - +(new Date(end));
Бен Расикот

Отлично. Хотя я предпочитаюreturn (Date.UTC(yr2, mo2-1, dy2) - Date.UTC(yr1, mo1-1, dy1)) / 86400000;
dcromley

13

Использование 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>


Moment.js действительно удобен для таких вещей, как разница между YTD иvar now = moment(), yearStart = moment().startOf('year'); var ytdDays = now.diff(yearStart, 'days'); // this can be years, months, weeks, days, hours, minutes, and seconds console.log(ytdDays); здесь: momentjs.com
Шариф,

11

Значения даты в 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

Лучше избавиться от 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

Чтобы рассчитать дни между 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>


9

Можно рассчитать полную разность дней доказательств между двумя датами, расположенными в разных TZ, используя следующую формулу:

var start = new Date('10/3/2015');
var end = new Date('11/2/2015');
var days = (end - start) / 1000 / 60 / 60 / 24;
console.log(days);
// actually its 30 ; but due to daylight savings will show 31.0xxx
// which you need to offset as below
days = days - (end.getTimezoneOffset() - start.getTimezoneOffset()) / (60 * 24);
console.log(days);


Это самый правильный ответ, вы должны принять во внимание DST! Спасибо
Gisway

6

Я нашел этот вопрос, когда хочу вычислить две даты, но дата имеет значение часов и минут, я изменил ответ @ michael-liu, чтобы он соответствовал моим требованиям, и он прошел мой тест.

разность дней 2012-12-31 23:00и 2013-01-01 01:00должна быть равна 1. (2 часа) разность дней 2012-12-31 01:00и 2013-01-01 23:00должна быть равна 1. (46 часов)

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

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

6
var start= $("#firstDate").datepicker("getDate");
var end= $("#SecondDate").datepicker("getDate");
var days = (end- start) / (1000 * 60 * 60 * 24);
 alert(Math.round(days));

пример jsfiddle :)


6

Я думаю, что решения не верны 100% Я бы использовал Ceil вместо пола , Round будет работать, но это не правильная операция.

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

4
Дни могут длиться более 24 часов, а минуты - более 60 секунд. Использование Math.ceil () в этих случаях может привести к избыточному пересчету.
Рич Догерти

5

Как насчет использования formatDate из виджета DatePicker? Вы можете использовать его для преобразования дат в формат отметки времени (миллисекунды с 01.01.1970), а затем выполнить простое вычитание.


5

function timeDifference(date1, date2) {
  var oneDay = 24 * 60 * 60; // hours*minutes*seconds
  var oneHour = 60 * 60; // minutes*seconds
  var oneMinute = 60; // 60 seconds
  var firstDate = date1.getTime(); // convert to milliseconds
  var secondDate = date2.getTime(); // convert to milliseconds
  var seconds = Math.round(Math.abs(firstDate - secondDate) / 1000); //calculate the diffrence in seconds
  // the difference object
  var difference = {
    "days": 0,
    "hours": 0,
    "minutes": 0,
    "seconds": 0,
  }
  //calculate all the days and substract it from the total
  while (seconds >= oneDay) {
    difference.days++;
    seconds -= oneDay;
  }
  //calculate all the remaining hours then substract it from the total
  while (seconds >= oneHour) {
    difference.hours++;
    seconds -= oneHour;
  }
  //calculate all the remaining minutes then substract it from the total 
  while (seconds >= oneMinute) {
    difference.minutes++;
    seconds -= oneMinute;
  }
  //the remaining seconds :
  difference.seconds = seconds;
  //return the difference object
  return difference;
}
console.log(timeDifference(new Date(2017,0,1,0,0,0),new Date()));


1
Могу ли я попросить вас добавить больше контекста вокруг вашего ответа. Ответы только на код трудно понять. Это поможет вам и будущим читателям, если вы сможете добавить больше информации в свой пост.
RBT

я хотел отредактировать, но я получал ошибки, я мог отправить редактирование :(.
Noreddine Belhadj Cheikh

2
@ N.Belhadj, вы можете заменить все эти циклы while простыми операциями div и mod (%)
Михаил Шишков

4

Возможно, это не самое элегантное решение, но, кажется, оно отвечает на вопрос относительно простым кусочком кода. Разве вы не можете использовать что-то вроде этого:

function dayDiff(startdate, enddate) {
  var dayCount = 0;

  while(enddate >= startdate) {
    dayCount++;
    startdate.setDate(startdate.getDate() + 1);
  }

return dayCount; 
}

Предполагается, что вы передаете объекты даты в качестве параметров.


4

Если у вас есть две временные метки Unix, вы можете использовать эту функцию (для большей ясности сделана более подробной):

// Calculate number of days between two unix timestamps
// ------------------------------------------------------------
var daysBetween = function(timeStampA, timeStampB) {
    var oneDay = 24 * 60 * 60 * 1000; // hours * minutes * seconds * milliseconds
    var firstDate = new Date(timeStampA * 1000);
    var secondDate = new Date(timeStampB * 1000);
    var diffDays = Math.round(Math.abs((firstDate.getTime() - secondDate.getTime())/(oneDay)));
    return diffDays;
};

Пример:

daysBetween(1096580303, 1308713220); // 2455

4

Будьте осторожны при использовании миллисекунд .

Date.getTime () возвращает миллисекунды и делает математическую операцию с миллисекунд требуется включить

  • Летнее время (DST)
  • проверка, имеют ли обе даты одинаковое время (часы, минуты, секунды, миллисекунды)
  • Удостоверьтесь в том, какое поведение дней требуется изменить: 19 сентября 2016 г. - 29 сентября 2016 г. = разница в 1 или 2 дня?

Пример из комментария выше - лучшее решение, которое я нашел до сих пор https://stackoverflow.com/a/11252167/2091095 . Но используйте +1 к его результату, если вы хотите, чтобы считать все вовлеченные дни.

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;
}

var diff = daysBetween($('#first').val(), $('#second').val()) + 1;

4

Date.prototype.days = function(to) {
  return Math.abs(Math.floor(to.getTime() / (3600 * 24 * 1000)) - Math.floor(this.getTime() / (3600 * 24 * 1000)))
}


console.log(new Date('2014/05/20').days(new Date('2014/05/23'))); // 3 days

console.log(new Date('2014/05/23').days(new Date('2014/05/20'))); // 3 days


3

У меня была такая же проблема в Angular. Я делаю копию, потому что иначе он перезапишет первое свидание. Обе даты должны иметь время 00:00:00 (очевидно)

 /*
* Deze functie gebruiken we om het aantal dagen te bereken van een booking.
* */
$scope.berekenDagen = function ()
{
    $scope.booking.aantalDagen=0;

    /*De loper is gelijk aan de startdag van je reservatie.
     * De copy is nodig anders overschijft angular de booking.van.
     * */
    var loper = angular.copy($scope.booking.van);

    /*Zolang de reservatie beschikbaar is, doorloop de weekdagen van je start tot einddatum.*/
    while (loper < $scope.booking.tot) {
        /*Tel een dag op bij je loper.*/
        loper.setDate(loper.getDate() + 1);
        $scope.booking.aantalDagen++;
    }

    /*Start datum telt natuurlijk ook mee*/
    $scope.booking.aantalDagen++;
    $scope.infomsg +=" aantal dagen: "+$scope.booking.aantalDagen;
};

3

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

var startDate= new Date("Mon Jan 01 2007 11:00:00");
var endDate  =new Date("Tue Jan 02 2007 12:50:00");
var timeStart = startDate.getTime();
var timeEnd = endDate.getTime();
var yearStart = startDate.getFullYear();
var yearEnd   = endDate.getFullYear();
if(yearStart == yearEnd)
 {
  var hourDiff = timeEnd - timeStart; 
  var secDiff = hourDiff / 1000;
  var minDiff = hourDiff / 60 / 1000; 
  var hDiff = hourDiff / 3600 / 1000; 
  var myObj = {};
  myObj.hours = Math.floor(hDiff);
  myObj.minutes = minDiff  
  if(myObj.hours >= 24)
   {
    console.log(Math.floor(myObj.hours/24) + "day(s) ago")
   } 
 else if(myObj.hours>0)
  {
   console.log(myObj.hours +"hour(s) ago")
  }
 else
  {
   console.log(Math.abs(myObj.minutes) +"minute(s) ago")
  }
}
else
{
var yearDiff = yearEnd - yearStart;
console.log( yearDiff +" year(s) ago");
}

Пожалуйста, объясните свой код, и вы решили проблему, просто вставка кода считается плохим ответом.
Марко Скаббиоло

2
Хотя этот код может ответить на вопрос, предоставление дополнительного контекста относительно того, как и / или почему он решает проблему, улучшит долгосрочную ценность ответа.
Майкл Паркер

Спасибо @ MarcoScabbiolo, @ Michael Parker за комментарии. Так как я новичок в Stackoverflow с точки зрения ответов, я не знал, как должно быть найдено решение
Ramees Rahath

3

Если вы хотите иметь DateArray с датами, попробуйте это:

<script>
        function getDates(startDate, stopDate) {
        var dateArray = new Array();
        var currentDate = moment(startDate);
        dateArray.push( moment(currentDate).format('L'));

        var stopDate = moment(stopDate);
        while (dateArray[dateArray.length -1] != stopDate._i) {
            dateArray.push( moment(currentDate).format('L'));
            currentDate = moment(currentDate).add(1, 'days');
        }
        return dateArray;
      }
</script>

DebugSnippet


3

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

var firstDate= new Date(firstDate.setHours(0,0,0,0));
var secondDate= new Date(secondDate.setHours(0,0,0,0));
var timeDiff = firstDate.getTime() - secondDate.getTime();
var diffDays =timeDiff / (1000 * 3600 * 24);

Проблема с вашим решением заключается в том, что вы предполагаете, что firstDate и secondDate являются датами, и тогда нет необходимости менять их на дату снова, и если они не являются датами *, которые не являются), вы получите ошибку на setHours. чтобы исправить это, вам нужно переместить setHours изnew Date
AaA

2
function formatDate(seconds, dictionary) {
    var foo = new Date;
    var unixtime_ms = foo.getTime();
    var unixtime = parseInt(unixtime_ms / 1000);
    var diff = unixtime - seconds;
    var display_date;
    if (diff <= 0) {
        display_date = dictionary.now;
    } else if (diff < 60) {
        if (diff == 1) {
            display_date = diff + ' ' + dictionary.second;
        } else {
            display_date = diff + ' ' + dictionary.seconds;
        }
    } else if (diff < 3540) {
        diff = Math.round(diff / 60);
        if (diff == 1) {
            display_date = diff + ' ' + dictionary.minute;
        } else {
            display_date = diff + ' ' + dictionary.minutes;
        }
    } else if (diff < 82800) {
        diff = Math.round(diff / 3600);
        if (diff == 1) {
            display_date = diff + ' ' + dictionary.hour;
        } else {
            display_date = diff + ' ' + dictionary.hours;
        }
    } else {
        diff = Math.round(diff / 86400);
        if (diff == 1) {
            display_date = diff + ' ' + dictionary.day;
        } else {
            display_date = diff + ' ' + dictionary.days;
        }
    }
    return display_date;
}

2

Простой, легкий и сложный. Эта функция будет вызываться каждые 1 секунду для обновления времени.

const year = (new Date().getFullYear());
const bdayDate = new Date("04,11,2019").getTime();  //mmddyyyy

// countdown
let timer = setInterval(function() {

// get today's date
const today = new Date().getTime();

// get the difference
const diff = bdayDate - today;

// math
let days = Math.floor(diff / (1000 * 60 * 60 * 24));
let hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
let minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
let seconds = Math.floor((diff % (1000 * 60)) / 1000);

}, 1000);

1

Лучшее решение от

Игнорирование части времени

он вернет 0, если обе даты совпадают.

function dayDiff(firstDate, secondDate) {
  firstDate = new Date(firstDate);
  secondDate = new Date(secondDate);
  if (!isNaN(firstDate) && !isNaN(secondDate)) {
    firstDate.setHours(0, 0, 0, 0); //ignore time part
    secondDate.setHours(0, 0, 0, 0); //ignore time part
    var dayDiff = secondDate - firstDate;
    dayDiff = dayDiff / 86400000; // divide by milisec in one day
    console.log(dayDiff);
  } else {
    console.log("Enter valid date.");
  }
}

$(document).ready(function() {
  $('input[type=datetime]').datepicker({
    dateFormat: "mm/dd/yy",
    changeMonth: true,
    changeYear: true
  });
  $("#button").click(function() {
    dayDiff($('#first').val(), $('#second').val());
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="//code.jquery.com/ui/1.12.1/jquery-ui.js"></script>

<input type="datetime" id="first" value="12/28/2016" />
<input type="datetime" id="second" value="12/28/2017" />
<input type="button" id="button" value="Calculate">


1

Вклад на дату до 1970-01-01 и после 2038-01-19

function DateDiff(aDate1, aDate2) {
  let dDay = 0;
  this.isBissexto = (aYear) => {
    return (aYear % 4 == 0 && aYear % 100 != 0) || (aYear % 400 == 0);
  };
  this.getDayOfYear = (aDate) => {
    let count = 0;
    for (let m = 0; m < aDate.getUTCMonth(); m++) {
      count += m == 1 ? this.isBissexto(aDate.getUTCFullYear()) ? 29 : 28 : /(3|5|8|10)/.test(m) ? 30 : 31;
    }
    count += aDate.getUTCDate();
    return count;
  };
  this.toDays = () => {
    return dDay;
  };
  (() => {
    let startDate = aDate1.getTime() <= aDate2.getTime() ? new Date(aDate1.toISOString()) : new Date(aDate2.toISOString());
    let endDate = aDate1.getTime() <= aDate2.getTime() ? new Date(aDate2.toISOString()) : new Date(aDate1.toISOString());
    while (startDate.getUTCFullYear() != endDate.getUTCFullYear()) {
      dDay += (this.isBissexto(startDate.getFullYear())? 366 : 365) - this.getDayOfYear(startDate) + 1;
      startDate = new Date(startDate.getUTCFullYear()+1, 0, 1);
    }
    dDay += this.getDayOfYear(endDate) - this.getDayOfYear(startDate);
  })();
}

0
   function validateDate() {
        // get dates from input fields
        var startDate = $("#startDate").val();
        var endDate = $("#endDate").val();
        var sdate = startDate.split("-");
        var edate = endDate.split("-");
        var diffd = (edate[2] - sdate[2]) + 1;
        var leap = [ 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ];
        var nonleap = [ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ];
        if (sdate[0] > edate[0]) {
            alert("Please enter End Date Year greater than Start Date Year");
            document.getElementById("endDate").value = "";
            diffd = "";
        } else if (sdate[1] > edate[1]) {
            alert("Please enter End Date month greater than Start Date month");
            document.getElementById("endDate").value = "";
            diffd = "";
        } else if (sdate[2] > edate[2]) {
            alert("Please enter End Date greater than Start Date");
            document.getElementById("endDate").value = "";
            diffd = "";
        } else {
            if (sdate[0] / 4 == 0) {
                while (sdate[1] < edate[1]) {
                    diffd = diffd + leap[sdate[1]++];
                }
            } else {
                while (sdate[1] < edate[1]) {
                    diffd = diffd + nonleap[sdate[1]++];
                }
            }
            document.getElementById("numberOfDays").value = diffd;
        }
    }

0

Вы можете использовать UnderscoreJS для форматирования и расчета разницы.

Демо https://jsfiddle.net/sumitridhal/8sv94msp/

 var startDate = moment("2016-08-29T23:35:01");
var endDate = moment("2016-08-30T23:35:01");  
  

console.log(startDate);
console.log(endDate);

var resultHours = endDate.diff(startDate, 'hours', true);

document.body.innerHTML = "";
document.body.appendChild(document.createTextNode(resultHours));
body { white-space: pre; font-family: monospace; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.5.1/moment.min.js"></script>

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.