Как получить количество дней между двумя датами в 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 The
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-это значения даты и времени.
Итак, прямые вычисления даты несовместимы:
(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 () возвращает миллисекунды и делаю математическая операция с миллисекундами требует включения
- переход на летнее и зимнее время
- проверка если обе даты имеют одинаковое время (часы, минуты, секунды, миллисекунды)
- убедитесь, что поведение дней diff требуется: 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; }это предполагает, что вы передаете объекты даты в качестве параметров.
У меня была такая же проблема в угловой. Я делаю копию, потому что иначе он перепишет первое свидание. Обе даты должны иметь время 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>);как первоначально отмечалось в комментариях к этому решению, вам не нужно предоставлять все эти значения, если они не нужны для даты создания.
Comments