如何在Javascript中以mm dd hh格式获取两个日期的差异

如何在Javascript中以mm dd hh格式获取两个日期的差异,javascript,angularjs,date,datetime,Javascript,Angularjs,Date,Datetime,我可以使用moment.js或plain js获得两个日期之间的差异 in moment.js var a = moment(timestamp1); var b = moment(timestamp2); var month =a.diff(b, 'month'); var day =a.diff(b, 'day') - month; var year =a.diff(b, 'hours'); 月返回月,天返回日差。但我想知道答案 MM DD hh格式,例如2个月12天5小时。我不能直接转换

我可以使用moment.js或plain js获得两个日期之间的差异

in moment.js

var a = moment(timestamp1);
var b = moment(timestamp2);
var month =a.diff(b, 'month');
var day =a.diff(b, 'day') - month;
var year =a.diff(b, 'hours');
月返回月,天返回日差。但我想知道答案


MM DD hh格式,例如2个月12天5小时。我不能直接转换日期,因为还有其他问题,如闰年。那么,还有其他办法全力以赴地计算一切吗?我在angular js中这样做,如果有任何帮助的话

您不能将差异(diff result是一个数字)转换为MM DD hh格式,因为有些月份的长度为30天,其他月份的长度为31天

 var date1 = new Date("4/14/2016");
 var date2 = new Date("10/16/2016");
 var timeDiff = Math.abs(date2.getTime() - date1.getTime());

 var newDate = new Date(timeDiff);
 alert(newDate);
 alert("Month " + (newDate.getUTCMonth() + 1));
 alert("Date " + newDate.getUTCDate());
 alert("Hour " + newDate.getUTCHours());
它可以从开始和结束日期时间计算

有一个类似的函数,你正在寻找,但不确切

moment("2010-01-01").from("2010-12-01")
结果:一年前

moment("2010-01-01").from("2010-12-01", true)

结果:一年

获得两个日期之间的精确差异并不简单,因为年、月和日的长度不同。此外,加法不一定与减法对称,例如,4月30日加一个月是5月30日,但5月31日加一个月是6月30日还是7月1日?与2月29日前后1年类似

下面将尝试处理这些问题,这样,如果添加一个月的时间超过了一个月,那么该日期将返回到上个月的最后一天。希望这些意见足够,如果没有,请澄清

dateDiff函数返回一个年、月、日等的值数组。若要获取MM DD hh,只需获取该值并以任何方式格式化即可。我包含了一个小的格式化函数,它只打印出非零组件

//根据时间值简单计算两个日期之间的天数
函数getDaysDiff(开始、结束){
返回((parseStringUTC(end)-parseStringUTC(start))/8.64e7.toFixed(2);
}
//需要ISO8601格式的输入:yyyy-mm-ddThh:mm:ss.sssZ
//总是期望UTC
函数解析字符串UTC(s){
s=s.split(/\D/);
s[6]=s[6]?('0.+s[6])*1000:0;
返回新日期(Date.UTC(s[0]、--s[1]、s[2]、s[3]| 0、s[4]| 0、s[5]| 0、s[6]| 0));
}
/*获取以年、月、日为单位的两个日期之间的差值,
**小时,分钟和秒。
**
**差异是要添加到较早日期以达到较晚日期的值。
**
*********************
**夏令时边界上的差异,因此使用UTC值(通过
**值为date.toISOString()或类似ISO 8601 UTC的格式)
**
**@param{string}d0-格式为y-m-d h:m:s的较早日期,也可以是
**yyyy mm ddThh:mm:ssZ,忽略时区偏移
**未验证该字符串
**@param{string}d1-以后的日期,格式同上。如果d1早于
**与d0相比,结果不可靠。
**@返回年、月、日、小时、分钟和的{Array}值
**秒(毫秒为秒的小数部分)
*/
函数dateDiff(d0,d1){
var s=d0.split(/\D/);
var e=d1.拆分(/\D/);
//计算组件的初始值,
//时间分量是可选的,缺少的值被视为零
var-ms=(e[6]| | 0)-(s[6]| | 0);
var-sec=(e[5]| | 0)-(s[5]| | 0);
var min=(e[4]| 0)-(s[4]| 0);
var-hr=(e[3]| | 0)-(s[3]| | 0);
var日=e[2]-s[2];
var mon=e[1]-s[1];
var yr=e[0]-s[0];
//借用以解析-ve值。
如果(ms<0){//ms从sec借用
ms+=1000;
--证券交易委员会;
}
如果(sec<0){//sec从min借用
sec+=60;
--闵;
}
如果(min<0){//min从hr借用
最小值+=60;
--人力资源;
}
如果(hr<0){//hr从日起借款
hr+=24;
--一天;
}
//Day从month借来,有点复杂,但不太难
如果(天<0){
var prevMonLen=新日期(e[0],e[1]-1,0).getDate();
//如果开始日期小于上个月的天数,
//将天数设置为上月长度+当前差异天数值
//请注意,当前的差异日可能已借用了一天,因此不要使用结束日期-开始日期
//否则,如果开始日期等于或大于
//上个月的天,只设置为结束日期。这是因为添加
//1月30日前的1个月应为2月的最后一天(即28日或29日),而不是3月2日或1日
//分别是,如果为1月30日的日期对象添加1个月,则会发生这种情况。
//同样,5月31日+1个月应该是6月30日,而不是7月1日。
日=s[2]=月末天数,且结束日期为最后一天
//月数,零个月,一个月加一
//如果月数=12,则为零,并将1与年相加
var endMonLen=新日期(e[0],e[1],0).getDate();
如果(日期>=endMonLen&s[2]>e[2]&e[2]==endMonLen){
日=0;
++周一;
如果(mon==12){
mon=0;
++年;
}
}
返回值[年、月、日、小时、分钟,+(秒+'.+('00'+ms).slice(-3));
}
/*格式化dateDiff函数的输出,例如3年、2天、23.12秒
**
**@param{Array}v-按年、月、日、小时、分钟顺序排列的值数组
**秒(毫秒为秒的小数部分)
**@返回{string}个附加名称的值。将“s”添加到其他值
**如果大于1,则忽略零值,例如未返回“0个月”。
*/
函数格式输出(v){
var值=[‘年’、‘月’、‘日’、‘小时’、‘分钟’、‘秒’]
返回v.reduce(函数(s,x,i){
s+=x?(s.长度?“”:“”)+
(i==5?x.toFixed(3):x)+''+值[i]+(x==1?'':''):'';
返回s;
}, '');
}
//测试,集中在二月
变量日期=[
['2016-01-31','2016-03-01'],//1个月1日-1月31日+1个月=2月29日
['2016-01-29','2016-03-01'],//1个月1天-1月29日+1个月=2月29日
['2016-01-27','2016-03-01'],//1个月3天-1月27日+1个月=2