![](/img/trans.png)
[英]How can I calculate the difference in years, months and days between two dates in Javascript?
[英]Difference between two dates in years, months, days in JavaScript
如何获取 JavaScript 中两个日期(年、月、日)之间的差异,例如:2010 年 4 月 10 日是 3 年 x 月 y 天前?
有很多解决方案,但它们只提供天或月或年格式的差异,或者它们不正确(意味着不考虑一个月或闰年等的实际天数)。 真的有那么难吗?
我看过:
在 php 中很容易,但不幸的是我只能在该项目上使用客户端脚本。 任何可以做到这一点的库或框架都可以。
以下是日期差异的预期输出列表:
//Expected output should be: "1 year, 5 months".
diffDate(new Date('2014-05-10'), new Date('2015-10-10'));
//Expected output should be: "1 year, 4 months, 29 days".
diffDate(new Date('2014-05-10'), new Date('2015-10-09'));
//Expected output should be: "1 year, 3 months, 30 days".
diffDate(new Date('2014-05-10'), new Date('2015-09-09'));
//Expected output should be: "9 months, 27 days".
diffDate(new Date('2014-05-10'), new Date('2015-03-09'));
//Expected output should be: "1 year, 9 months, 28 days".
diffDate(new Date('2014-05-10'), new Date('2016-03-09'));
//Expected output should be: "1 year, 10 months, 1 days".
diffDate(new Date('2014-05-10'), new Date('2016-03-11'));
您需要精确到什么程度? 如果您确实需要考虑普通年和闰年,以及月份之间天数的确切差异,那么您将不得不编写更高级的东西,但对于基本和粗略的计算,这应该可以解决问题:
today = new Date()
past = new Date(2010,05,01) // remember this is equivalent to 06 01 2010
//dates in js are counted from 0, so 05 is june
function calcDate(date1,date2) {
var diff = Math.floor(date1.getTime() - date2.getTime());
var day = 1000 * 60 * 60 * 24;
var days = Math.floor(diff/day);
var months = Math.floor(days/31);
var years = Math.floor(months/12);
var message = date2.toDateString();
message += " was "
message += days + " days "
message += months + " months "
message += years + " years ago \n"
return message
}
a = calcDate(today,past)
console.log(a) // returns Tue Jun 01 2010 was 1143 days 36 months 3 years ago
请记住,这是不精确的,为了完全精确地计算日期,必须有一个日历并知道一年是否是闰年,我计算月数的方式也只是近似值.
但是你可以很容易地改进它。
实际上,有一个 moment.js 插件的解决方案,而且非常简单。
不要重新发明轮子。
只需插入Moment.js 日期范围插件。
var starts = moment('2014-02-03 12:53:12'); var ends = moment(); var duration = moment.duration(ends.diff(starts)); // with ###moment precise date range plugin### // it will tell you the difference in human terms var diff = moment.preciseDiff(starts, ends, true); // example: { "years": 2, "months": 7, "days": 0, "hours": 6, "minutes": 29, "seconds": 17, "firstDateWasLater": false } // or as string: var diffHuman = moment.preciseDiff(starts, ends); // example: 2 years 7 months 6 hours 29 minutes 17 seconds document.getElementById('output1').innerHTML = JSON.stringify(diff) document.getElementById('output2').innerHTML = diffHuman
<html> <head> <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.14.1/moment.min.js"></script> <script src="https://raw.githubusercontent.com/codebox/moment-precise-range/master/moment-precise-range.js"></script> </head> <body> <h2>Difference between "NOW and 2014-02-03 12:53:12"</h2> <span id="output1"></span> <br /> <span id="output2"></span> </body> </html>
将其修改为更加准确。 它将日期转换为 'YYYY-MM-DD' 格式,忽略 HH:MM:SS,并采用可选的 endDate 或使用当前日期,并且不关心值的顺序。
function dateDiff(startingDate, endingDate) { var startDate = new Date(new Date(startingDate).toISOString().substr(0, 10)); if (!endingDate) { endingDate = new Date().toISOString().substr(0, 10); // need date in YYYY-MM-DD format } var endDate = new Date(endingDate); if (startDate > endDate) { var swap = startDate; startDate = endDate; endDate = swap; } var startYear = startDate.getFullYear(); var february = (startYear % 4 === 0 && startYear % 100 !== 0) || startYear % 400 === 0 ? 29 : 28; var daysInMonth = [31, february, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; var yearDiff = endDate.getFullYear() - startYear; var monthDiff = endDate.getMonth() - startDate.getMonth(); if (monthDiff < 0) { yearDiff--; monthDiff += 12; } var dayDiff = endDate.getDate() - startDate.getDate(); if (dayDiff < 0) { if (monthDiff > 0) { monthDiff--; } else { yearDiff--; monthDiff = 11; } dayDiff += daysInMonth[startDate.getMonth()]; } return yearDiff + 'Y ' + monthDiff + 'M ' + dayDiff + 'D'; } // Examples let dates = [ ['2019-05-10','2019-05-10'], // 0Y 0M 0D ['2019-05-09','2019-05-10'], // 0Y 0M 1D ['2018-05-09','2019-05-10'], // 1Y 0M 1D ['2018-05-18','2019-05-10'], // 0Y 11M 23D ['2019-01-09','2019-05-10'], // 0Y 4M 1D ['2019-02-10','2019-05-10'], // 0Y 3M 0D ['2019-02-11','2019-05-10'], // 0Y 2M 27D ['2016-02-11','2019-05-10'], // 3Y 2M 28D - leap year ['1972-11-30','2019-05-10'], // 46Y 5M 10D ['2016-02-11','2017-02-11'], // 1Y 0M 0D ['2016-02-11','2016-03-10'], // 0Y 0M 28D - leap year ['2100-02-11','2100-03-10'], // 0Y 0M 27D - not a leap year ['2017-02-11','2016-02-11'], // 1Y 0M 0D - swapped dates to return correct result [new Date() - 1000 * 60 * 60 * 24,'2019-05-10'] // 0Y 0M 1D ].forEach(([s, e]) => console.log(dateDiff(s, e)));
较旧的不太准确但更简单的版本
@RajeevPNadig 的答案是我正在寻找的,但他的代码返回的值不正确。 这不是很准确,因为它假设从 1970 年 1 月 1 日开始的日期序列与任何其他相同天数的序列相同。 例如,它将 7 月 1 日到 9 月 1 日(62 天)的差异计算为 0Y 2M 3D 而不是 0Y 2M 0D,因为 1970 年 1 月 1 日加上 62 天是 3 月 3 日。
// startDate must be a date string
function dateAgo(date) {
var startDate = new Date(date);
var diffDate = new Date(new Date() - startDate);
return ((diffDate.toISOString().slice(0, 4) - 1970) + "Y " +
diffDate.getMonth() + "M " + (diffDate.getDate()-1) + "D");
}
然后你可以像这样使用它:
// based on a current date of 2018-03-09
dateAgo('1972-11-30'); // "45Y 3M 9D"
dateAgo('2017-03-09'); // "1Y 0M 0D"
dateAgo('2018-01-09'); // "0Y 2M 0D"
dateAgo('2018-02-09'); // "0Y 0M 28D" -- a little odd, but not wrong
dateAgo('2018-02-01'); // "0Y 1M 5D" -- definitely "feels" wrong
dateAgo('2018-03-09'); // "0Y 0M 0D"
如果您的用例只是日期字符串,那么如果您只想要一个快速而肮脏的 4 班轮,这可以正常工作。
我使用这个简单的代码来获取当前日期的年、月、日的差异。
var sdt = new Date('1972-11-30');
var difdt = new Date(new Date() - sdt);
alert((difdt.toISOString().slice(0, 4) - 1970) + "Y " + (difdt.getMonth()+1) + "M " + difdt.getDate() + "D");
我认为您正在寻找与我想要的相同的东西。 我尝试使用 javascript 提供的毫秒差异来做到这一点,但这些结果在现实世界的日期中不起作用。 如果您想要 2016 年 2 月 1 日和 2017 年 1 月 31 日之间的差异,我想要的结果是 1 年 0 个月和 0 天。 整整一年(假设您将最后一天算作一整天,例如公寓的租约)。 但是,毫秒方法将为您提供 1 年 0 个月和 1 天,因为日期范围包括闰年。 所以这是我在 javascript 中为我的 adobe 表单使用的代码(您可以命名字段):(已编辑,我纠正了一个错误)
var f1 = this.getField("LeaseExpiration");
var g1 = this.getField("LeaseStart");
var end = f1.value
var begin = g1.value
var e = new Date(end);
var b = new Date(begin);
var bMonth = b.getMonth();
var bYear = b.getFullYear();
var eYear = e.getFullYear();
var eMonth = e.getMonth();
var bDay = b.getDate();
var eDay = e.getDate() + 1;
if ((eMonth == 0)||(eMonth == 2)||(eMonth == 4)|| (eMonth == 6) || (eMonth == 7) ||(eMonth == 9)||(eMonth == 11))
{
var eDays = 31;
}
if ((eMonth == 3)||(eMonth == 5)||(eMonth == 8)|| (eMonth == 10))
{
var eDays = 30;
}
if (eMonth == 1&&((eYear % 4 == 0) && (eYear % 100 != 0)) || (eYear % 400 == 0))
{
var eDays = 29;
}
if (eMonth == 1&&((eYear % 4 != 0) || (eYear % 100 == 0)))
{
var eDays = 28;
}
if ((bMonth == 0)||(bMonth == 2)||(bMonth == 4)|| (bMonth == 6) || (bMonth == 7) ||(bMonth == 9)||(bMonth == 11))
{
var bDays = 31;
}
if ((bMonth == 3)||(bMonth == 5)||(bMonth == 8)|| (bMonth == 10))
{
var bDays = 30;
}
if (bMonth == 1&&((bYear % 4 == 0) && (bYear % 100 != 0)) || (bYear % 400 == 0))
{
var bDays = 29;
}
if (bMonth == 1&&((bYear % 4 != 0) || (bYear % 100 == 0)))
{
var bDays = 28;
}
var FirstMonthDiff = bDays - bDay + 1;
if (eDay - bDay < 0)
{
eMonth = eMonth - 1;
eDay = eDay + eDays;
}
var daysDiff = eDay - bDay;
if(eMonth - bMonth < 0)
{
eYear = eYear - 1;
eMonth = eMonth + 12;
}
var monthDiff = eMonth - bMonth;
var yearDiff = eYear - bYear;
if (daysDiff == eDays)
{
daysDiff = 0;
monthDiff = monthDiff + 1;
if (monthDiff == 12)
{
monthDiff = 0;
yearDiff = yearDiff + 1;
}
}
if ((FirstMonthDiff != bDays)&&(eDay - 1 == eDays))
{
daysDiff = FirstMonthDiff;
}
event.value = yearDiff + " Year(s)" + " " + monthDiff + " month(s) " + daysDiff + " days(s)"
为此,我创建了另一个函数:
function dateDiff(date) {
date = date.split('-');
var today = new Date();
var year = today.getFullYear();
var month = today.getMonth() + 1;
var day = today.getDate();
var yy = parseInt(date[0]);
var mm = parseInt(date[1]);
var dd = parseInt(date[2]);
var years, months, days;
// months
months = month - mm;
if (day < dd) {
months = months - 1;
}
// years
years = year - yy;
if (month * 100 + day < mm * 100 + dd) {
years = years - 1;
months = months + 12;
}
// days
days = Math.floor((today.getTime() - (new Date(yy + years, mm + months - 1, dd)).getTime()) / (24 * 60 * 60 * 1000));
//
return {years: years, months: months, days: days};
}
不需要任何 3rd 方库。 接受一个参数—— YYYY-MM-DD 格式的日期。
https://gist.github.com/lemmon/d27c2d4a783b1cf72d1d1cc243458d56
使用 dayjs,我们是这样做的:
export const getAgeDetails = (oldDate: dayjs.Dayjs, newDate: dayjs.Dayjs) => {
const years = newDate.diff(oldDate, 'year');
const months = newDate.diff(oldDate, 'month') - years * 12;
const days = newDate.diff(oldDate.add(years, 'year').add(months, 'month'), 'day');
return {
years,
months,
days,
allDays: newDate.diff(oldDate, 'day'),
};
};
它完美地计算了它,包括闰年和不同月份的天数。
为了快速方便地使用,我前段时间编写了这个函数。 它以一种很好的格式返回两个日期之间的差异。 随意使用它(在 webkit 上测试)。
/**
* Function to print date diffs.
*
* @param {Date} fromDate: The valid start date
* @param {Date} toDate: The end date. Can be null (if so the function uses "now").
* @param {Number} levels: The number of details you want to get out (1="in 2 Months",2="in 2 Months, 20 Days",...)
* @param {Boolean} prefix: adds "in" or "ago" to the return string
* @return {String} Diffrence between the two dates.
*/
function getNiceTime(fromDate, toDate, levels, prefix){
var lang = {
"date.past": "{0} ago",
"date.future": "in {0}",
"date.now": "now",
"date.year": "{0} year",
"date.years": "{0} years",
"date.years.prefixed": "{0} years",
"date.month": "{0} month",
"date.months": "{0} months",
"date.months.prefixed": "{0} months",
"date.day": "{0} day",
"date.days": "{0} days",
"date.days.prefixed": "{0} days",
"date.hour": "{0} hour",
"date.hours": "{0} hours",
"date.hours.prefixed": "{0} hours",
"date.minute": "{0} minute",
"date.minutes": "{0} minutes",
"date.minutes.prefixed": "{0} minutes",
"date.second": "{0} second",
"date.seconds": "{0} seconds",
"date.seconds.prefixed": "{0} seconds",
},
langFn = function(id,params){
var returnValue = lang[id] || "";
if(params){
for(var i=0;i<params.length;i++){
returnValue = returnValue.replace("{"+i+"}",params[i]);
}
}
return returnValue;
},
toDate = toDate ? toDate : new Date(),
diff = fromDate - toDate,
past = diff < 0 ? true : false,
diff = diff < 0 ? diff * -1 : diff,
date = new Date(new Date(1970,0,1,0).getTime()+diff),
returnString = '',
count = 0,
years = (date.getFullYear() - 1970);
if(years > 0){
var langSingle = "date.year" + (prefix ? "" : ""),
langMultiple = "date.years" + (prefix ? ".prefixed" : "");
returnString += (count > 0 ? ', ' : '') + (years > 1 ? langFn(langMultiple,[years]) : langFn(langSingle,[years]));
count ++;
}
var months = date.getMonth();
if(count < levels && months > 0){
var langSingle = "date.month" + (prefix ? "" : ""),
langMultiple = "date.months" + (prefix ? ".prefixed" : "");
returnString += (count > 0 ? ', ' : '') + (months > 1 ? langFn(langMultiple,[months]) : langFn(langSingle,[months]));
count ++;
} else {
if(count > 0)
count = 99;
}
var days = date.getDate() - 1;
if(count < levels && days > 0){
var langSingle = "date.day" + (prefix ? "" : ""),
langMultiple = "date.days" + (prefix ? ".prefixed" : "");
returnString += (count > 0 ? ', ' : '') + (days > 1 ? langFn(langMultiple,[days]) : langFn(langSingle,[days]));
count ++;
} else {
if(count > 0)
count = 99;
}
var hours = date.getHours();
if(count < levels && hours > 0){
var langSingle = "date.hour" + (prefix ? "" : ""),
langMultiple = "date.hours" + (prefix ? ".prefixed" : "");
returnString += (count > 0 ? ', ' : '') + (hours > 1 ? langFn(langMultiple,[hours]) : langFn(langSingle,[hours]));
count ++;
} else {
if(count > 0)
count = 99;
}
var minutes = date.getMinutes();
if(count < levels && minutes > 0){
var langSingle = "date.minute" + (prefix ? "" : ""),
langMultiple = "date.minutes" + (prefix ? ".prefixed" : "");
returnString += (count > 0 ? ', ' : '') + (minutes > 1 ? langFn(langMultiple,[minutes]) : langFn(langSingle,[minutes]));
count ++;
} else {
if(count > 0)
count = 99;
}
var seconds = date.getSeconds();
if(count < levels && seconds > 0){
var langSingle = "date.second" + (prefix ? "" : ""),
langMultiple = "date.seconds" + (prefix ? ".prefixed" : "");
returnString += (count > 0 ? ', ' : '') + (seconds > 1 ? langFn(langMultiple,[seconds]) : langFn(langSingle,[seconds]));
count ++;
} else {
if(count > 0)
count = 99;
}
if(prefix){
if(returnString == ""){
returnString = langFn("date.now");
} else if(past)
returnString = langFn("date.past",[returnString]);
else
returnString = langFn("date.future",[returnString]);
}
return returnString;
}
一些数学是有序的。
您可以在 Javascript 中从另一个 Date 对象中减去一个 Date 对象,您将以毫秒为单位得到它们之间的差异。 从此结果中,您可以提取所需的其他部分(天、月等)
例如:
var a = new Date(2010, 10, 1);
var b = new Date(2010, 9, 1);
var c = a - b; // c equals 2674800000,
// the amount of milisseconds between September 1, 2010
// and August 1, 2010.
现在你可以得到任何你想要的部分。 例如,两个日期之间经过了多少天:
var days = (a - b) / (60 * 60 * 24 * 1000);
// 60 * 60 * 24 * 1000 is the amount of milisseconds in a day.
// the variable days now equals 30.958333333333332.
差不多31天了。 然后,您可以向下舍入 30 天,并使用剩余的任何内容来获得小时、分钟等的数量。
如果您使用date-fns
并且不想安装Moment.js
或moment-precise-range-plugin
。 您可以使用以下date-fns
函数获得与 moment-precise-range-plugin 相同的结果
intervalToDuration({
start: new Date(),
end: new Date("24 Jun 2020")
})
这将在 JSON 对象中提供输出,如下所示
{
"years": 0,
"months": 0,
"days": 0,
"hours": 19,
"minutes": 35,
"seconds": 24
}
使用平面 Javascript:
function dateDiffInDays(start, end) {
var MS_PER_DAY = 1000 * 60 * 60 * 24;
var a = new Date(start);
var b = new Date(end);
const diffTime = Math.abs(a - b);
const diffDays = Math.ceil(diffTime / MS_PER_DAY);
console.log("Days: ", diffDays);
// Discard the time and time-zone information.
const utc1 = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate());
const utc2 = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate());
return Math.floor((utc2 - utc1) / MS_PER_DAY);
}
function dateDiffInDays_Months_Years(start, end) {
var m1 = new Date(start);
var m2 = new Date(end);
var yDiff = m2.getFullYear() - m1.getFullYear();
var mDiff = m2.getMonth() - m1.getMonth();
var dDiff = m2.getDate() - m1.getDate();
if (dDiff < 0) {
var daysInLastFullMonth = getDaysInLastFullMonth(start);
if (daysInLastFullMonth < m1.getDate()) {
dDiff = daysInLastFullMonth + dDiff + (m1.getDate() -
daysInLastFullMonth);
} else {
dDiff = daysInLastFullMonth + dDiff;
}
mDiff--;
}
if (mDiff < 0) {
mDiff = 12 + mDiff;
yDiff--;
}
console.log('Y:', yDiff, ', M:', mDiff, ', D:', dDiff);
}
function getDaysInLastFullMonth(day) {
var d = new Date(day);
console.log(d.getDay() );
var lastDayOfMonth = new Date(d.getFullYear(), d.getMonth() + 1, 0);
console.log('last day of month:', lastDayOfMonth.getDate() ); //
return lastDayOfMonth.getDate();
}
使用moment.js :
function dateDiffUsingMoment(start, end) {
var a = moment(start,'M/D/YYYY');
var b = moment(end,'M/D/YYYY');
var diffDaysMoment = b.diff(a, 'days');
console.log('Moments.js : ', diffDaysMoment);
preciseDiffMoments(a,b);
}
function preciseDiffMoments( a, b) {
var m1= a, m2=b;
m1.add(m2.utcOffset() - m1.utcOffset(), 'minutes'); // shift timezone of m1 to m2
var yDiff = m2.year() - m1.year();
var mDiff = m2.month() - m1.month();
var dDiff = m2.date() - m1.date();
if (dDiff < 0) {
var daysInLastFullMonth = moment(m2.year() + '-' + (m2.month() + 1),
"YYYY-MM").subtract(1, 'M').daysInMonth();
if (daysInLastFullMonth < m1.date()) { // 31/01 -> 2/03
dDiff = daysInLastFullMonth + dDiff + (m1.date() -
daysInLastFullMonth);
} else {
dDiff = daysInLastFullMonth + dDiff;
}
mDiff--;
}
if (mDiff < 0) {
mDiff = 12 + mDiff;
yDiff--;
}
console.log('getMomentum() Y:', yDiff, ', M:', mDiff, ', D:', dDiff);
}
使用以下示例测试了上述功能:
var sample1 = all('2/13/2018', '3/15/2018'); // {'M/D/YYYY'} 30, Y: 0 , M: 1 , D: 2
console.log(sample1);
var sample2 = all('10/09/2019', '7/7/2020'); // 272, Y: 0 , M: 8 , D: 29
console.log(sample2);
function all(start, end) {
dateDiffInDays(start, end);
dateDiffInDays_Months_Years(start, end);
try {
dateDiffUsingMoment(start, end);
} catch (e) {
console.log(e);
}
}
另一个解决方案,基于一些 PHP 代码。 strtotime 函数也基于 PHP,可在此处找到:http: //phpjs.org/functions/strtotime/ 。
Date.dateDiff = function(d1, d2) {
d1 /= 1000;
d2 /= 1000;
if (d1 > d2) d2 = [d1, d1 = d2][0];
var diffs = {
year: 0,
month: 0,
day: 0,
hour: 0,
minute: 0,
second: 0
}
$.each(diffs, function(interval) {
while (d2 >= (d3 = Date.strtotime('+1 '+interval, d1))) {
d1 = d3;
++diffs[interval];
}
});
return diffs;
};
用法:
> d1 = new Date(2000, 0, 1)
Sat Jan 01 2000 00:00:00 GMT+0100 (CET)
> d2 = new Date(2013, 9, 6)
Sun Oct 06 2013 00:00:00 GMT+0200 (CEST)
> Date.dateDiff(d1, d2)
Object {
day: 5
hour: 0
minute: 0
month: 9
second: 0
year: 13
}
很老的线程,我知道,但这是我的贡献,因为线程还没有解决。
它考虑了闰年,并且不假定每月或每年有任何固定的天数。
它在边境案件中可能存在缺陷,因为我没有对其进行彻底测试,但它适用于原始问题中提供的所有日期,因此我很有信心。
function calculate() { var fromDate = document.getElementById('fromDate').value; var toDate = document.getElementById('toDate').value; try { document.getElementById('result').innerHTML = ''; var result = getDateDifference(new Date(fromDate), new Date(toDate)); if (result && !isNaN(result.years)) { document.getElementById('result').innerHTML = result.years + ' year' + (result.years == 1 ? ' ' : 's ') + result.months + ' month' + (result.months == 1 ? ' ' : 's ') + 'and ' + result.days + ' day' + (result.days == 1 ? '' : 's'); } } catch (e) { console.error(e); } } function getDateDifference(startDate, endDate) { if (startDate > endDate) { console.error('Start date must be before end date'); return null; } var startYear = startDate.getFullYear(); var startMonth = startDate.getMonth(); var startDay = startDate.getDate(); var endYear = endDate.getFullYear(); var endMonth = endDate.getMonth(); var endDay = endDate.getDate(); // We calculate February based on end year as it might be a leep year which might influence the number of days. var february = (endYear % 4 == 0 && endYear % 100 != 0) || endYear % 400 == 0 ? 29 : 28; var daysOfMonth = [31, february, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; var startDateNotPassedInEndYear = (endMonth < startMonth) || endMonth == startMonth && endDay < startDay; var years = endYear - startYear - (startDateNotPassedInEndYear ? 1 : 0); var months = (12 + endMonth - startMonth - (endDay < startDay ? 1 : 0)) % 12; // (12 + ...) % 12 makes sure index is always between 0 and 11 var days = startDay <= endDay ? endDay - startDay : daysOfMonth[(12 + endMonth - 1) % 12] - startDay + endDay; return { years: years, months: months, days: days }; }
<p><input type="text" name="fromDate" id="fromDate" placeholder="yyyy-mm-dd" value="1999-02-28" /></p> <p><input type="text" name="toDate" id="toDate" placeholder="yyyy-mm-dd" value="2000-03-01" /></p> <p><input type="button" name="calculate" value="Calculate" onclick="javascript:calculate();" /></p> <p /> <p id="result"></p>
let startDate = moment(new Date('2017-05-12')); // yyyy-MM-dd
let endDate = moment(new Date('2018-09-14')); // yyyy-MM-dd
let Years = newDate.diff(date, 'years');
let months = newDate.diff(date, 'months');
let days = newDate.diff(date, 'days');
console.log("Year: " + Years, ", Month: " months-(Years*12), ", Days: " days-(Years*365.25)-((365.25*(days- (Years*12)))/12));
上面的代码段将打印:年:1,月:4,天:2
此函数能够返回类似自然语言的文本。 使用它来获得如下响应:
“4年1个月11天”
“1年2个月”
“11个月零20天”
“12天”
重要提示: date-fns是一个依赖项
只需复制下面的代码并将过去的日期插入我们的getElapsedTime函数! 它会将输入的日期与当前时间进行比较,并返回类似人类的响应。
import * as dateFns from "https://cdn.skypack.dev/date-fns@2.22.1";
function getElapsedTime(pastDate) {
const duration = dateFns.intervalToDuration({
start: new Date(pastDate),
end: new Date(),
});
let [years, months, days] = ["", "", ""];
if (duration.years > 0) {
years = duration.years === 1 ? "1 year" : `${duration.years} years`;
}
if (duration.months > 0) {
months = duration.months === 1 ? "1 month" : `${duration.months} months`;
}
if (duration.days > 0) {
days = duration.days === 1 ? "1 day" : `${duration.days} days`;
}
let response = [years, months, days].filter(Boolean);
switch (response.length) {
case 3:
response[1] += " and";
response[0] += ",";
break;
case 2:
response[0] += " and";
break;
}
return response.join(" ");
}
此链接具有最佳答案http://forums.asp.net/t/1610039.aspx?如何+如何+计算+差异+之间+两个+日期+年+年
您只需要添加几天的验证即可,例如:
如果(firstDate.getDate()<= now.getDate())
我使用一堆函数来做到这一点。 纯 JavaScript 和精确。
此代码包括计算天、月和年时差的函数。 其中之一可用于获取精确的时差,例如X years, Y months, Z days
。 在代码的最后,我提供了一些测试。
这个怎么运作:
getDaysDiff()
:
将时间差从毫秒转换为天。
getYearsDiff()
:
无需担心两个日期的月份和日期的影响。 该函数通过前后移动日期来计算年差。
getMonthsDiff()
(这与问题无关,但在calExactTimeDiff()
中使用了这个概念,我认为有人可能需要这样的函数,所以我插入它):
这个有点棘手。 艰苦的工作是处理两个日期的月份和日期。
如果endDate
的月份大于startDate
的月份,这意味着又过了一年(12 个月)。 但这是在monthsOfFullYears
中处理的,所以唯一需要做的是添加endDate
和startDate
月份的减法。
如果startDate
的月份大于endDate
的月份,则没有另一年。 所以我们应该得到它们之间的区别。 想象一下,我们想从今年的第10
个月到明年的第2
个月。 我们可以这样: 11, 12, 1, 2
。 所以我们过了4
个月。 这等于12 - (10 - 2)
。 我们得到月份之间的差异,然后从一年中的月份中减去它。
下一步是照顾好几个月的日子。 如果endDate
的日期大于或等于startDate
这意味着又过了一个月。 所以我们给它加1
。 但如果它更少,那么就没有什么可担心的了。 但是在我的代码中我没有这样做。 因为当我添加月份之间的差异时,我假设月份的天数是相等的。 所以我已经添加了1
。 因此,如果endDate
的日期小于startDate
,我必须将months
减少1
。
有一个例外:如果月份相等并且endDate
的日期小于startDate
的,月份应该是11
。
我在calExactTimeDiff()
中使用了相同的概念。
希望有用:)
// time difference in Days function getDaysDiff(startDate = new Date(), endDate = new Date()) { if (startDate > endDate) [startDate, endDate] = [endDate, startDate]; let timeDiff = endDate - startDate; let timeDiffInDays = Math.floor(timeDiff / (1000 * 3600 * 24)); return timeDiffInDays; } // time difference in Months function getMonthsDiff(startDate = new Date(), endDate = new Date()) { let monthsOfFullYears = getYearsDiff(startDate, endDate) * 12; let months = monthsOfFullYears; // the variable below is not necessary, but I kept it for understanding of code // we can use "startDate" instead of it let yearsAfterStart = new Date( startDate.getFullYear() + getYearsDiff(startDate, endDate), startDate.getMonth(), startDate.getDate() ); let isDayAhead = endDate.getDate() >= yearsAfterStart.getDate(); if (startDate.getMonth() == endDate.getMonth() && !isDayAhead) { months = 11; return months; } if (endDate.getMonth() >= yearsAfterStart.getMonth()) { let diff = endDate.getMonth() - yearsAfterStart.getMonth(); months += (isDayAhead) ? diff : diff - 1; } else { months += isDayAhead ? 12 - (startDate.getMonth() - endDate.getMonth()) : 12 - (startDate.getMonth() - endDate.getMonth()) - 1; } return months; } // time difference in Years function getYearsDiff(startDate = new Date(), endDate = new Date()) { if (startDate > endDate) [startDate, endDate] = [endDate, startDate]; let yearB4End = new Date( endDate.getFullYear() - 1, endDate.getMonth(), endDate.getDate() ); let year = 0; year = yearB4End > startDate ? yearB4End.getFullYear() - startDate.getFullYear() : 0; let yearsAfterStart = new Date( startDate.getFullYear() + year + 1, startDate.getMonth(), startDate.getDate() ); if (endDate >= yearsAfterStart) year++; return year; } // time difference in format: X years, Y months, Z days function calExactTimeDiff(firstDate, secondDate) { if (firstDate > secondDate) [firstDate, secondDate] = [secondDate, firstDate]; let monthDiff = 0; let isDayAhead = secondDate.getDate() >= firstDate.getDate(); if (secondDate.getMonth() >= firstDate.getMonth()) { let diff = secondDate.getMonth() - firstDate.getMonth(); monthDiff += (isDayAhead) ? diff : diff - 1; } else { monthDiff += isDayAhead ? 12 - (firstDate.getMonth() - secondDate.getMonth()) : 12 - (firstDate.getMonth() - secondDate.getMonth()) - 1; } let dayDiff = 0; if (isDayAhead) { dayDiff = secondDate.getDate() - firstDate.getDate(); } else { let b4EndDate = new Date( secondDate.getFullYear(), secondDate.getMonth() - 1, firstDate.getDate() ) dayDiff = getDaysDiff(b4EndDate, secondDate); } if (firstDate.getMonth() == secondDate.getMonth() && !isDayAhead) monthDiff = 11; let exactTimeDiffUnits = { yrs: getYearsDiff(firstDate, secondDate), mths: monthDiff, dys: dayDiff, }; return `${exactTimeDiffUnits.yrs} years, ${exactTimeDiffUnits.mths} months, ${exactTimeDiffUnits.dys} days` } let s = new Date(2012, 4, 12); let e = new Date(2008, 5, 24); console.log(calExactTimeDiff(s, e)); s = new Date(2001, 7, 4); e = new Date(2016, 6, 9); console.log(calExactTimeDiff(s, e)); s = new Date(2011, 11, 28); e = new Date(2021, 3, 6); console.log(calExactTimeDiff(s, e)); s = new Date(2020, 8, 7); e = new Date(2021, 8, 6); console.log(calExactTimeDiff(s, e));
以天、小时、分钟、秒、毫秒为单位的时间跨度:
// Extension for Date
Date.difference = function (dateFrom, dateTo) {
var diff = { TotalMs: dateTo - dateFrom };
diff.Days = Math.floor(diff.TotalMs / 86400000);
var remHrs = diff.TotalMs % 86400000;
var remMin = remHrs % 3600000;
var remS = remMin % 60000;
diff.Hours = Math.floor(remHrs / 3600000);
diff.Minutes = Math.floor(remMin / 60000);
diff.Seconds = Math.floor(remS / 1000);
diff.Milliseconds = Math.floor(remS % 1000);
return diff;
};
// Usage
var a = new Date(2014, 05, 12, 00, 5, 45, 30); //a: Thu Jun 12 2014 00:05:45 GMT+0400
var b = new Date(2014, 02, 12, 00, 0, 25, 0); //b: Wed Mar 12 2014 00:00:25 GMT+0400
var diff = Date.difference(b, a);
/* diff: {
Days: 92
Hours: 0
Minutes: 5
Seconds: 20
Milliseconds: 30
TotalMs: 7949120030
} */
这两个代码都不适合我,所以我用这个代替了几个月和几天:
function monthDiff(d2, d1) {
var months;
months = (d2.getFullYear() - d1.getFullYear()) * 12;
months -= d1.getMonth() + 1;
months += d2.getMonth() + 1;
return months <= 0 ? 0 : months;
}
function daysInMonth(date) {
return new Date(date.getYear(), date.getMonth() + 1, 0).getDate();
}
function diffDate(date1, date2) {
if (date2 && date2.getTime() && !isNaN(date2.getTime())) {
var months = monthDiff(date1, date2);
var days = 0;
if (date1.getUTCDate() >= date2.getUTCDate()) {
days = date1.getUTCDate() - date2.getUTCDate();
}
else {
months--;
days = date1.getUTCDate() - date2.getUTCDate() + daysInMonth(date2);
}
// Use the variables months and days how you need them.
}
}
以下是给出正确但不完全精确的算法,因为它没有考虑闰年。 它还假设一个月有 30 天。 例如,一个很好的用法是,如果某人居住在12/11/2010到11/10/2011的地址中,它可以很快告诉这个人在那里住了 10 个月零 29 天。 从12/11/2010到11/12/2011是 11 个月零 1 天。 对于某些类型的应用,这种精度就足够了。 这适用于这些类型的应用程序,因为它旨在简化:
var datediff = function(start, end) {
var diff = { years: 0, months: 0, days: 0 };
var timeDiff = end - start;
if (timeDiff > 0) {
diff.years = end.getFullYear() - start.getFullYear();
diff.months = end.getMonth() - start.getMonth();
diff.days = end.getDate() - start.getDate();
if (diff.months < 0) {
diff.years--;
diff.months += 12;
}
if (diff.days < 0) {
diff.months = Math.max(0, diff.months - 1);
diff.days += 30;
}
}
return diff;
};
使用 TypeScript/JavaScript 计算年、月、日、分、秒、毫秒中两个日期之间的差异
dateDifference(actualDate) {
// Calculate time between two dates:
const date1 = actualDate; // the date you already commented/ posted
const date2: any = new Date(); // today
let r = {}; // object for clarity
let message: string;
const diffInSeconds = Math.abs(date2 - date1) / 1000;
const days = Math.floor(diffInSeconds / 60 / 60 / 24);
const hours = Math.floor(diffInSeconds / 60 / 60 % 24);
const minutes = Math.floor(diffInSeconds / 60 % 60);
const seconds = Math.floor(diffInSeconds % 60);
const milliseconds =
Math.round((diffInSeconds - Math.floor(diffInSeconds)) * 1000);
const months = Math.floor(days / 31);
const years = Math.floor(months / 12);
// the below object is just optional
// if you want to return an object instead of a message
r = {
years: years,
months: months,
days: days,
hours: hours,
minutes: minutes,
seconds: seconds,
milliseconds: milliseconds
};
// check if difference is in years or months
if (years === 0 && months === 0) {
// show in days if no years / months
if (days > 0) {
if (days === 1) {
message = days + ' day';
} else { message = days + ' days'; }
} else if (hours > 0) {
if (hours === 1) {
message = hours + ' hour';
} else {
message = hours + ' hours';
}
} else {
// show in minutes if no years / months / days
if (minutes === 1) {
message = minutes + ' minute';
} else {message = minutes + ' minutes';}
}
} else if (years === 0 && months > 0) {
// show in months if no years
if (months === 1) {
message = months + ' month';
} else {message = months + ' months';}
} else if (years > 0) {
// show in years if years exist
if (years === 1) {
message = years + ' year';
} else {message = years + ' years';}
}
return 'Posted ' + message + ' ago';
// this is the message a user see in the view
}
但是,您可以更新消息的上述逻辑以显示秒和毫秒,或者使用对象“r”以任何您想要的方式格式化消息。
如果你想直接复制代码,你可以在这里查看我上面的代码的要点
我知道这是一个旧线程,但我想根据@Pawel Miech 的答案投入我的 2 美分。
确实,您需要将差异转换为毫秒,然后您需要进行一些数学运算。 但请注意,您需要以反向方式进行数学运算,即您需要计算年、月、日、小时和分钟。
我曾经做过这样的事情:
var mins;
var hours;
var days;
var months;
var years;
var diff = new Date() - new Date(yourOldDate);
// yourOldDate may be is coming from DB, for example, but it should be in the correct format ("MM/dd/yyyy hh:mm:ss:fff tt")
years = Math.floor((diff) / (1000 * 60 * 60 * 24 * 365));
diff = Math.floor((diff) % (1000 * 60 * 60 * 24 * 365));
months = Math.floor((diff) / (1000 * 60 * 60 * 24 * 30));
diff = Math.floor((diff) % (1000 * 60 * 60 * 24 * 30));
days = Math.floor((diff) / (1000 * 60 * 60 * 24));
diff = Math.floor((diff) % (1000 * 60 * 60 * 24));
hours = Math.floor((diff) / (1000 * 60 * 60));
diff = Math.floor((diff) % (1000 * 60 * 60));
mins = Math.floor((diff) / (1000 * 60));
但是,当然,这并不精确,因为它假设所有年份都有 365 天,所有月份都有 30 天,这并非在所有情况下都是正确的。
它非常简单,请使用下面的代码,它将根据 //3 年 9 个月 3 周 5 天 15 小时 50 分钟给出该格式的差异
Date.getFormattedDateDiff = function(date1, date2) {
var b = moment(date1),
a = moment(date2),
intervals = ['years','months','weeks','days'],
out = [];
for(var i=0; i<intervals.length; i++){
var diff = a.diff(b, intervals[i]);
b.add(diff, intervals[i]);
out.push(diff + ' ' + intervals[i]);
}
return out.join(', ');
};
var today = new Date(),
newYear = new Date(today.getFullYear(), 0, 1),
y2k = new Date(2000, 0, 1);
//(AS OF NOV 29, 2016)
//Time since New Year: 0 years, 10 months, 4 weeks, 0 days
console.log( 'Time since New Year: ' + Date.getFormattedDateDiff(newYear, today) );
//Time since Y2K: 16 years, 10 months, 4 weeks, 0 days
console.log( 'Time since Y2K: ' + Date.getFormattedDateDiff(y2k, today) );
通过使用Moment库和一些自定义逻辑,我们可以获得确切的日期差异
var out; out = diffDate(new Date('2014-05-10'), new Date('2015-10-10')); display(out); out = diffDate(new Date('2014-05-10'), new Date('2015-10-09')); display(out); out = diffDate(new Date('2014-05-10'), new Date('2015-09-09')); display(out); out = diffDate(new Date('2014-05-10'), new Date('2015-03-09')); display(out); out = diffDate(new Date('2014-05-10'), new Date('2016-03-09')); display(out); out = diffDate(new Date('2014-05-10'), new Date('2016-03-11')); display(out); function diffDate(startDate, endDate) { var b = moment(startDate), a = moment(endDate), intervals = ['years', 'months', 'weeks', 'days'], out = {}; for (var i = 0; i < intervals.length; i++) { var diff = a.diff(b, intervals[i]); b.add(diff, intervals[i]); out[intervals[i]] = diff; } return out; } function display(obj) { var str = ''; for (key in obj) { str = str + obj[key] + ' ' + key + ' ' } console.log(str); }
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.js"></script>
这段代码应该会给你想要的结果
//************************** Enter your dates here **********************//
var startDate = "10/05/2014";
var endDate = "11/3/2016"
//******* and press "Run", you will see the result in a popup *********//
var noofdays = 0;
var sdArr = startDate.split("/");
var startDateDay = parseInt(sdArr[0]);
var startDateMonth = parseInt(sdArr[1]);
var startDateYear = parseInt(sdArr[2]);
sdArr = endDate.split("/")
var endDateDay = parseInt(sdArr[0]);
var endDateMonth = parseInt(sdArr[1]);
var endDateYear = parseInt(sdArr[2]);
console.log(startDateDay+' '+startDateMonth+' '+startDateYear);
var yeardays = 365;
var monthArr = [31,,31,30,31,30,31,31,30,31,30,31];
var noofyears = 0
var noofmonths = 0;
if((startDateYear%4)==0) monthArr[1]=29;
else monthArr[1]=28;
if(startDateYear == endDateYear){
noofyears = 0;
noofmonths = getMonthDiff(startDate,endDate);
if(noofmonths < 0) noofmonths = 0;
noofdays = getDayDiff(startDate,endDate);
}else{
if(endDateMonth < startDateMonth){
noofyears = (endDateYear - startDateYear)-1;
if(noofyears < 1) noofyears = 0;
}else{
noofyears = endDateYear - startDateYear;
}
noofmonths = getMonthDiff(startDate,endDate);
if(noofmonths < 0) noofmonths = 0;
noofdays = getDayDiff(startDate,endDate);
}
alert(noofyears+' year, '+ noofmonths+' months, '+ noofdays+' days');
function getDayDiff(startDate,endDate){
if(endDateDay >=startDateDay){
noofdays = 0;
if(endDateDay > startDateDay) {
noofdays = endDateDay - startDateDay;
}
}else{
if((endDateYear%4)==0) {
monthArr[1]=29;
}else{
monthArr[1] = 28;
}
if(endDateMonth != 1)
noofdays = (monthArr[endDateMonth-2]-startDateDay) + endDateDay;
else
noofdays = (monthArr[11]-startDateDay) + endDateDay;
}
return noofdays;
}
function getMonthDiff(startDate,endDate){
if(endDateMonth > startDateMonth){
noofmonths = endDateMonth - startDateMonth;
if(endDateDay < startDateDay){
noofmonths--;
}
}else{
noofmonths = (12-startDateMonth) + endDateMonth;
if(endDateDay < startDateDay){
noofmonths--;
}
}
return noofmonths;
}
您应该尝试使用date-fns 。 这是我使用date- fns 中的intervalToDuration和formatDuration函数的方法。
let startDate = Date.parse("2010-10-01 00:00:00 UTC");
let endDate = Date.parse("2020-11-01 00:00:00 UTC");
let duration = intervalToDuration({start: startDate, end: endDate});
let durationInWords = formatDuration(duration, {format: ["years", "months", "days"]}); //output: 10 years 1 month
因为我必须使用moment-hijri (回历)并且不能使用 moment.diff() 方法,所以我想出了这个解决方案。 也可以与 moment.js 一起使用
var momenti = require('moment-hijri')
//calculate hijri
var strt = await momenti(somedateobject)
var until = await momenti()
var years = await 0
var months = await 0
var days = await 0
while(strt.valueOf() < until.valueOf()){
await strt.add(1, 'iYear');
await years++
}
await strt.subtract(1, 'iYear');
await years--
while(strt.valueOf() < until.valueOf()){
await strt.add(1, 'iMonth');
await months++
}
await strt.subtract(1, 'iMonth');
await months--
while(strt.valueOf() < until.valueOf()){
await strt.add(1, 'day');
await days++
}
await strt.subtract(1, 'day');
await days--
await console.log(years)
await console.log(months)
await console.log(days)
目前(截至 2022 年 3 月 5 日)处于活动提案第 3 阶段的 ECMAScript “临时 API”解决方案,这将是我们将来(很快)执行此操作的方法。
这是当前temporal-polyfill的解决方案
<script type='module'> import * as TemporalModule from 'https://cdn.jsdelivr.net/npm/@js-temporal/polyfill@0.3.0/dist/index.umd.js' const Temporal = temporal.Temporal; //---------------------------------------- function dateDiff(start, end, maxUnit) { return (Temporal.PlainDate.from(start).until(Temporal.PlainDate.from(end),{largestUnit:maxUnit}).toString()).match(/(\d*Y)|(\d*M)|(\d*D)/g).join(" "); } //---------------------------------------- console.log("Diff in (years, months, days): ",dateDiff("1963-02-03","2022-03-06","year")) console.log("Diff in (months, days) : ",dateDiff("1963-02-03","2022-03-06","month")) console.log("Diff in (days) : ",dateDiff("1963-02-03","2022-03-06","day")) </script>
您的预期输出不正确。 例如'2014-05-10'
和'2015-03-09'
之间的区别不是9个月,27天正确答案是
(05-10 to 05-31) = 21 days
(2014-06 to 2015-03) = 9 months
(03-01 to 03-09) = 9 days
total is 9 months and 30 days
警告:一个理想的函数会知道每个月的闰年和天数,但我发现这个函数的结果对于我当前的任务来说足够准确,所以我和你分享了
function diffDate(date1, date2) { var daysDiff = Math.ceil((Math.abs(date1 - date2)) / (1000 * 60 * 60 * 24)); var years = Math.floor(daysDiff / 365.25); var remainingDays = Math.floor(daysDiff - (years * 365.25)); var months = Math.floor((remainingDays / 365.25) * 12); var days = Math.ceil(daysDiff - (years * 365.25 + (months / 12 * 365.25))); return { daysAll: daysDiff, years: years, months: months, days:days } } console.log(diffDate(new Date('2014-05-10'), new Date('2015-10-10'))); console.log(diffDate(new Date('2014-05-10'), new Date('2015-10-09'))); console.log(diffDate(new Date('2014-05-10'), new Date('2015-09-09'))); console.log(diffDate(new Date('2014-05-10'), new Date('2015-03-09'))); console.log(diffDate(new Date('2014-05-10'), new Date('2016-03-09'))); console.log(diffDate(new Date('2014-05-10'), new Date('2016-03-11')));
有几个 npm 包可以帮助做到这一点。 以下是从各种来源收集的列表。 我发现 date-fns 版本是最简单的。
您可以使用 date-fns 中的intervalToDuration
、formatDuration
来人性化所需格式的持续时间,如下所示:
import { intervalToDuration, formatDuration } from 'date-fns'
let totalDuration = intervalToDuration({
start: new Date(1929, 0, 15, 12, 0, 0),
end: new Date(1968, 3, 4, 19, 5, 0)
});
let textDuration = formatDuration(totalDuration, { format: ['years', 'months'], delimiter: ', ' })
// Output: "39 years, 2 months"
从这里克隆上面的代码以便自己尝试: https ://runkit.com/embed/diu9o3qe53j4
您可以使用 luxon 提取日期之间的持续时间并使用人性化持续时间将其人性化,如下所示:
const DateTime = luxon.DateTime; const Interval = luxon.Interval; const start = DateTime.fromSQL("2020-06-19 11:14:00"); const finish = DateTime.fromSQL("2020-06-21 13:11:00"); const formatted = Interval .fromDateTimes(start, finish) .toDuration() .valueOf(); console.log(humanizeDuration(formatted)) // output: 2 days, 1 hour, 57 minutes console.log(humanizeDuration(formatted, { language: 'es' })) // output: 2 días, 1 hora, 57 minutos console.log(humanizeDuration(formatted, { language: 'ru' })) // output: 2 дня, 1 час, 57 минут
<script src="https://cdn.jsdelivr.net/npm/luxon@1.25.0/build/global/luxon.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/humanize-duration@3.25.1/humanize-duration.min.js"></script>
参考上述代码: https ://stackoverflow.com/a/65651515/6908282
我知道这是一个古老而漫长的话题,我相信已经有很多很好的答案,但我想补充两点——一个简单而透明的解决方案,它独立于任何库并且可以精确地工作。 只需将所有魔法留在 javascript 日期 object 上。
function 需要两个 ISO 格式的日期(它们的顺序无关紧要),返回带有years
、 months
和days
的 object(以及label
)。
它可以很容易地延长数小时、数分钟等。希望对您有所帮助。
dateRange(firstDate = "1979-07-07", secondDate = "2022-11-19") {
const dateA = new Date(firstDate);
const dateB = new Date(secondDate);
if (dateA.getTime() === dateB.getTime()) {
return {
years: 0,
months: 0,
days: 0,
label: "The dates are the same.",
};
}
let startDate = null;
let endDate = null;
//the date range should be computed in absolute values
//it doesn't matter, in which order the dates are supplied
//so, simply said, startDate = min(dateA, dateB) and endDate = max(dateA, dateB)
if (dateA < dateB) {
startDate = dateA;
//subtracting 1 day from the end date in order to get correct values
endDate = new Date(
dateB.getFullYear(),
dateB.getMonth(),
dateB.getDate() - 1,
);
} else if (dateA > dateB) {
startDate = dateB;
endDate = new Date(
dateA.getFullYear(),
dateA.getMonth(),
dateA.getDate() - 1,
);
}
//setting controlDate which will be incremented until reaching endDate
let controlDate = startDate;
//setting differences in years, months and days
let yearsDiff = 0;
let monthsDiff = 0;
let daysDiff = 0;
//incrementing by years until exceeding end date
do {
yearsDiff++;
controlDate = new Date(
startDate.getFullYear() + yearsDiff,
startDate.getMonth(),
startDate.getDate(),
);
} while (controlDate.getTime() <= endDate.getTime());
//end date exceeded, so decrement yearsDiff
yearsDiff--;
//incrementing by months until exceeding end date
do {
monthsDiff++;
controlDate = new Date(
startDate.getFullYear() + yearsDiff,
startDate.getMonth() + monthsDiff,
startDate.getDate(),
);
} while (controlDate.getTime() <= endDate.getTime());
//end date exceeded, so decrement monthsDiff
monthsDiff--;
//incrementing by days until exceeding end date
do {
daysDiff++;
controlDate = new Date(
startDate.getFullYear() + yearsDiff,
startDate.getMonth() + monthsDiff,
startDate.getDate() + daysDiff,
);
} while (controlDate.getTime() <= endDate.getTime());
//end date exceeded - daysDiff keeps final value
return {
years: yearsDiff,
months: monthsDiff,
days: daysDiff,
label:
"" +
yearsDiff +
" year(s), " +
monthsDiff +
" month(s), " +
daysDiff +
" day(s).",
};
}
我会亲自使用http://www.datejs.com/ ,非常方便。 具体来说,查看 time.js 文件:http ://code.google.com/p/datejs/source/browse/trunk/src/time.js
我这样做。 精确的? 也许也许不是。 试试看
<html>
<head>
<title> Age Calculator</title>
</head>
<input type="date" id="startDate" value="2000-01-01">
<input type="date" id="endDate" value="2020-01-01">
<button onclick="getAge(new Date(document.getElementById('startDate').value), new Date(document.getElementById('endDate').value))">Check Age</button>
<script>
function getAge (startDate, endDate) {
var diff = endDate-startDate
var age = new Date(new Date("0000-01-01").getTime()+diff)
var years = age.getFullYear()
var months = age.getMonth()
var days = age.getDate()
console.log(years,"years",months,"months",days-1,"days")
return (years+"years "+ months+ "months"+ days,"days")
}
</script>
</html>
这对我有用。
function GetDateDifference(date, otherDate) {
var dateOnly = date.setHours(0, 0, 0, 0);
var otherDateOnly = otherDate.setHours(0, 0, 0, 0);
var milliseconds = Math.abs(dateOnly - otherDateOnly);
var millisecondsPerDay = 1000 * 60 * 60 * 24;
return Math.floor(milliseconds / millisecondsPerDay);
}
我在遇到同样的问题时偶然发现了这一点。 这是我的代码。 它完全依赖 JS 日期函数,所以处理闰年,并且不根据小时比较天数,所以它避免了夏令时问题。
function dateDiff(start, end) { let years = 0, months = 0, days = 0; // Day diffence. Trick is to use setDate(0) to get the amount of days // from the previous month if the end day less than the start day. if (end.getDate() < start.getDate()) { months = -1; let datePtr = new Date(end); datePtr.setDate(0); days = end.getDate() + (datePtr.getDate() - start.getDate()); } else { days = end.getDate() - start.getDate(); } if (end.getMonth() < start.getMonth() || (end.getMonth() === start.getMonth() && end.getDate() < start.getDate())) { years = -1; months += end.getMonth() + (12 - start.getMonth()); } else { months += end.getMonth() - start.getMonth(); } years += end.getFullYear() - start.getFullYear(); console.log(`${years}y ${months}m ${days}d`); return [years, months, days]; } let a = new Date(2019,6,31); // 31 Jul 2019 let b = new Date(2022,2, 1); // 1 Mar 2022 console.log(dateDiff(a, b)); // [2, 7, -2]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.