Chr*_*ris 41 javascript datediff date
我现在已经搜索了4个小时,并且没有找到解决方案来获取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'));
Run Code Online (Sandbox Code Playgroud)
Paw*_*ech 29
你需要多精确?如果你确实需要考虑常见的年份和闰年,以及几个月之间天数的确切差异,那么你将不得不写一些更高级的东西,但是为了进行基本和粗略的计算,这应该可以解决问题:
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
Run Code Online (Sandbox Code Playgroud)
请记住,这是不精确的,为了计算完全精确的日期,必须有一个日历并知道一年是否是闰年,我计算月数的方式也只是近似值.
但你可以轻松改进它.
Ina*_*mus 18
实际上,有一个带有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 = diffHumanRun Code Online (Sandbox Code Playgroud)
<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>Run Code Online (Sandbox Code Playgroud)
Mor*_*red 16
对此进行了修改,使其更加准确。它将日期转换为 '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';
}
Run Code Online (Sandbox Code Playgroud)
然后你可以像这样使用它:
// based on a current date of 2019-05-10
dateDiff('2019-05-10'); // 0Y 0M 0D
dateDiff('2019-05-09'); // 0Y 0M 1D
dateDiff('2018-05-09'); // 1Y 0M 1D
dateDiff('2018-05-18'); // 0Y 11M 23D
dateDiff('2019-01-09'); // 0Y 4M 1D
dateDiff('2019-02-10'); // 0Y 3M 0D
dateDiff('2019-02-11'); // 0Y 2M 27D
dateDiff('2016-02-11'); // 3Y 2M 28D - leap year
dateDiff('1972-11-30'); // 46Y 5M 10D
dateDiff('2016-02-11', '2017-02-11'); // 1Y 0M 0D
dateDiff('2016-02-11', '2016-03-10'); // 0Y 0M 28D - leap year
dateDiff('2100-02-11', '2100-03-10'); // 0Y 0M 27D - not a leap year
dateDiff('2017-02-11', '2016-02-11'); // 1Y 0M 0D - swapped dates to return correct result
dateDiff(new Date() - 1000 * 60 * 60 * 24); // 0Y 0M 1D
Run Code Online (Sandbox Code Playgroud)
较旧的不太准确但更简单的版本
@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");
}
Run Code Online (Sandbox Code Playgroud)
然后你可以像这样使用它:
// 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"
Run Code Online (Sandbox Code Playgroud)
如果您的用例只是日期字符串,那么如果您只想要一个快速而肮脏的 4 班轮,这可以正常工作。
Raj*_*dig 12
我用这个简单的代码来区分当前日期的年,月,日.
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");
Run Code Online (Sandbox Code Playgroud)
对于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'),
};
};
Run Code Online (Sandbox Code Playgroud)
它完美地计算它,包括闰年和不同月份的天数。
小智 7
如果您正在使用date-fns并且不想安装 Moment.js或moment-precise-range-plugin. 您可以使用以下date-fns函数获得与 moment-precise-range-plugin 相同的结果
intervalToDuration({
start: new Date(),
end: new Date("24 Jun 2020")
})
Run Code Online (Sandbox Code Playgroud)
这将在 JSON 对象中提供输出,如下所示
{
"years": 0,
"months": 0,
"days": 0,
"hours": 19,
"minutes": 35,
"seconds": 24
}
Run Code Online (Sandbox Code Playgroud)
实例https://stackblitz.com/edit/react-wvxvql
链接到文档https://date-fns.org/v2.14.0/docs/intervalToDuration
小智 6
为此,我创建了另一个函数:
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};
}
Run Code Online (Sandbox Code Playgroud)
不需要任何 3rd 方库。采用一个参数——YYYY-MM-DD 格式的日期。
https://gist.github.com/lemmon/d27c2d4a783b1cf72d1d1cc243458d56
为了方便快捷,我前段时间写了这个函数.它以漂亮的格式返回两个日期之间的差异.随意使用它(在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;
}
Run Code Online (Sandbox Code Playgroud)
我认为您正在寻找与我想要的东西相同的东西。我尝试使用javascript提供的毫秒数来执行此操作,但这些结果在实际的日期世界中不起作用。如果您想要2016年2月1日与2017年1月31日之间的差额,我想要的结果是1年0个月0天。正好一年(假设您将最后一天算作一整天,就像租住公寓一样)。但是,由于日期范围包括a年,因此毫秒方法将为您提供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)"
Run Code Online (Sandbox Code Playgroud)
我个人会使用http://www.datejs.com/,非常方便。具体来说,查看 time.js 文件:http://code.google.com/p/datejs/source/browse/trunk/src/time.js