Как получить количество дней между двумя датами в JavaScript?
Как получить количество дней между двумя датами в 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>
30 ответов
здесь и реализация 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 даты (без" UTC " в имени) работают в локальном часовом поясе браузера пользователя, поэтому в целом вы можете столкнуться с проблемами, если ваш пользователь находится в часовом поясе, который вы не ожидаете, и вашему коду придется иметь дело с переходами на летнее время. Вы должны внимательно прочитать документацию для объекта Date и его методов, а для чего-либо более сложного настоятельно рассмотреть возможность использования библиотеки, которая предлагает более безопасные и мощные API для манипулирования датой.
кроме того, для иллюстрации, фрагмент используется им доступ на window
объект для краткости, но в производстве вы должны использовать стандартизированные API, такие как getElementById, или, что более вероятно, некоторые рамки пользовательского интерфейса.
на момент написания этой статьи только один из других ответов правильно обрабатывает переходы 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 am Pacific Standard Time (UTC-08:00) хранится как 3/10/2013 8:00 AM UTC, а 3/11/2013 12:00 am Pacific Daylight Time (UTC-07:00) хранится как 3/11/2013 7:00 AM UTC. В этот день с полуночи до полуночи местное время составляет всего 23 часа в UTC!
хотя день по местному времени может иметь более или менее 24 часов, день в UTC всегда ровно 24 часа.1 на daysBetween
метод, показанный выше, использует этот факт, сначала вызывая treatAsUTC
чтобы настроить оба местных времени до полуночи UTC, перед вычитанием и делением.
1. JavaScript игнорирует високосные секунды.
самый простой способ получить разницу между двумя датами:
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;
}
}
Я рекомендую использовать момент.библиотека js (http://momentjs.com/docs/#/displaying/difference/). Он правильно обрабатывает летнее время и в целом отлично подходит для работы.
пример:
var start = moment("2013-11-03");
var end = moment("2013-11-04");
end.diff(start, "days")
1
Я бы пошел вперед и возьмите эту небольшую утилиту и в ней вы найдете функции для этого для вас. Вот краткий пример:
<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>
Через Минуту.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>
значения даты в JS являются значениями datetime.
таким образом, прямые вычисления даты несовместимы:
(2013-11-05 00:00:00) - (2013-11-04 10:10:10) < 1 day
например, нам нужно преобразовать de 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);
для расчета дней между 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>
лучше избавиться от DST, Math.сейл, математика.пол и т. д. используя время 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
один день в миллисекундах.
Как насчет использования formatDate из виджета DatePicker? Вы можете использовать его для преобразования дат в формате метки времени (миллисекунды с 01/01/1970), а затем выполнить простое вычитание.
я нашел этот вопрос, когда я хочу сделать некоторые вычисления на две даты, но дата имеет значение часов и минут, я изменил ответ @michael-liu в соответствии с моим требованием, и он прошел мой тест.
diff дней 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);
}
Я думаю, что решения не являются правильными 100% я бы использовал ceil вместо Пол, раунд будет работать, но это не правильно операцию.
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)
};
}
можно рассчитать полную разницу дней доказательства между двумя датами, покоящимися на разных TZs, используя следующую формулу:
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);
var start= $("#firstDate").datepicker("getDate");
var end= $("#SecondDate").datepicker("getDate");
var days = (end- start) / (1000 * 60 * 60 * 24);
alert(Math.round(days));
jsfiddle пример :)
будьте осторожны, когда через миллисекунд.
на дата.методов 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;
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()));
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
это может быть не самое элегантное решение, но, по-моему, оно отвечает на вопрос относительно простым битом кода. Вы не можете использовать что-то вроде этого:
function dayDiff(startdate, enddate) {
var dayCount = 0;
while(enddate >= startdate) {
dayCount++;
startdate.setDate(startdate.getDate() + 1);
}
return dayCount;
}
это предполагает, что вы передаете объекты date в качестве параметров.
У меня была такая же проблема в угловой. Я делаю копию, потому что иначе он перепишет первое свидание. Обе даты должны иметь время 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;
};
Если у вас есть две временные метки 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
я использовал код ниже, чтобы поэкспериментировать с функциональностью даты публикации для сообщения новостей.Я вычисляю минуту или час, день или год на основе даты разноски и текущей даты.
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");
}
Если вы хотите иметь 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>
простой способ вычисления дней между двумя датами-удалить оба их компонента времени, т. е. установить часы, минуты, секунды и миллисекунды до 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);
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)
- установить дату начала
- установить дату окончания
- вычислить разницу
- преобразование миллисекунд в дни
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;
}
лучшее решение
игнорирование части времени
он вернет 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">
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;
}
}
вы можете использовать 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>
букмарклет версия других ответов, запрашивая вас для обеих дат:
javascript:(function() {
var d = new Date(prompt("First Date or leave blank for today?") || Date.now());
prompt("Days Between", Math.round(
Math.abs(
(d.getTime() - new Date(prompt("Date 2")).getTime())
/(24*60*60*1000)
)
));
})();
вот ответ, первоначально размещенный на https://stackoverflow.com/a/1968175/3787376.
Метод включает в себя полезную функцию, которую я создал, чтобы получить разницу, разделенную на единицы времени.
С помощью дата объект и его значение миллисекунды, различия могут быть вычислены:
var a = new Date(); // Current date now.
var b = new Date(2010, 0, 1, 0, 0, 0, 0); // Start of 2010.
var d = (b-a); // Difference in milliseconds.
вы можете получить количество секунд (как целое число / целое число), разделив миллисекунды на 1000, чтобы преобразовать его в секундах, а затем преобразование результата в целое число (это удаляет дробную часть, представляющую миллисекунды):
var seconds = parseInt((b-a)/1000);
вы могли бы тогда получить целое minutes
деление seconds
на 60 и преобразования его в целое число, то hours
деление minutes
60 и преобразование его в целое число, а затем более длительные единицы времени таким же образом. Из этого функция для получения максимального количества единицы времени в значении нижней единицы и оставшейся нижней единицы может быть создано:
function get_whole_values(base_value, time_fractions) {
time_data = [base_value];
for (i = 0; i < time_fractions.length; i++) {
time_data.push(parseInt(time_data[i]/time_fractions[i]));
time_data[i] = time_data[i] % time_fractions[i];
}; return time_data;
};
// Input variables below: starting value of 72000 milliseconds, time fractions are
// 1000 (amount of milliseconds in a second) and 60 (amount of seconds in a minute).
console.log(get_whole_values(72000, [1000, 60]));
// -> [0,12,1] # 0 whole milliseconds, 12 whole seconds, 1 whole minute.
параметры ввода, указанные выше для второго дата объект использовать следующий формат:
new Date(<year>, <month>, <day>, <hours>, <minutes>, <seconds>, <milliseconds>);
как первоначально отмечалось в комментариях к этому решению, вам не нужно предоставлять все эти значения, если они не нужны для даты создания.