adding, subtracting, duration problems
lutzbickhardt opened this issue · comments
Describe the bug
I have come across some peculiarities when adding and subtracting dates and getting durations between dates.
- years before BC (negative years) do not work at all.
- durations do not include leapdays (the doc mentions this, but should it not include leapdays?, maybe new function?)
- adding across years is wrong (at least in my examples)
To Reproduce
`const moment= require("moment");
const dayjs= require("dayjs");
var newA, newS;
const dateTime= "2023-12-31T12:00:00";
var Y=M=D=h=m=s= 0;
var newA= moment(dateTime).add(Y,"years").add(M,"months").add(D,"days").add(h,"hours").add(m,"minutes").add(s,"seconds");
var newS= moment(dateTime).subtract(Y,"years").subtract(M,"months").subtract(D,"days").subtract(h,"hours").subtract(m,"minutes").subtract(s,"seconds");
console.log("[moment] add ZERO", newA, "is OK");
console.log("[moment] sub ZERO", newS, "is OK");
Y= 2023, M= 12, D= 31, h=12, m= 0, s= 0;
newA= moment(dateTime).add(Y,"years").add(M,"months").add(D,"days").add(h,"hours").add(m,"minutes").add(s,"seconds");
newS= moment(dateTime).subtract(Y,"years").subtract(M,"months").subtract(D,"days").subtract(h,"hours").subtract(m,"minutes").subtract(s,"seconds");
const leapdays= Math.floor(Y/4) - Math.floor(Y/400) + Math.floor(Y/2000);
console.log("[moment] add SAME", newA, "expected 4047-12-31T00:00:00+01:00, not counting ", leapdays, "leapdays");
console.log("[moment] sub SAME", newS, "expected -0001-12-31T00:00:00+01:00, not counting ", leapdays, "leapdays");
//
Y=M=D=h=m=s= 0;
var _newA= dayjs(dateTime).add(Y,"years").add(M,"months").add(D,"days").add(h,"hours").add(m,"minutes").add(s,"seconds");
var _newS= dayjs(dateTime).subtract(Y,"years").subtract(M,"months").subtract(D,"days").subtract(h,"hours").subtract(m,"minutes").subtract(s,"seconds");
console.log("[dayjs] add ZERO", JSON.stringify(_newA), "is OK");
console.log("[dayjs] sub ZERO", JSON.stringify(_newS), "is OK");
Y= 2023, M= 12, D= 31, h=12, m= 0, s= 0;
_newA= dayjs(dateTime).add(Y,"years").add(M,"months").add(D,"days").add(h,"hours").add(m,"minutes").add(s,"seconds");
_newS= dayjs(dateTime).subtract(Y,"years").subtract(M,"months").subtract(D,"days").subtract(h,"hours").subtract(m,"minutes").subtract(s,"seconds");
console.log("[dayjs] add SAME", JSON.stringify(_newA), "expected 4047-12-31T00:00:00, not counting ", leapdays, "leapdays");
console.log("[dayjs] sub SAME", JSON.stringify(_newS), "expected -0001-12-31T00:00:00, not counting ", leapdays, "leapdays");
// duration
var mDT= new moment(dateTime);
const new_dt= moment.duration(mDT.diff(mDT));
const new_dtA= moment.duration(mDT.diff(newA));
const new_dtS= moment.duration(mDT.diff(newS));
const expA= "4047-12-31T00:00:00";
//const expS= "-0001-12-31T00:00:00";
const new_dtexpA= moment.duration(mDT.diff(expA));
//const new_dtexpS= moment.duration(mDT.diff(expS));
console.log("[moment] duration ZERO ->", new_dt.get('year')+"-"+ new_dt.get('month')+"-" + new_dt.get('day') +" "+ new_dt.get('hour'), "is OK");
console.log("[moment] duration SAME ->", new_dtA.get('year')+"-"+ new_dtA.get('month')+"-" + new_dtA.get('day') +" "+ new_dtA.get('hour'), "exp: (+/-)2023-12-31 12");
console.log("[moment] duration -SAME ->", new_dtS.get('year')+"-"+ new_dtS.get('month')+"-" + new_dtS.get('day') +" "+ new_dtS.get('hour'), "exp: (+/-)2023-12-31 12");
console.log("[moment] duration expected SAME ->", new_dtexpA.get('year')+"-"+ new_dtexpA.get('month')+"-" + new_dtexpA.get('day') +" "+ new_dtexpA.get('hour'), "exp: (+/-)2023-12-31 12");
//console.log("[moment] duration expected -SAME ->", new_dtexpS.get('year')+"-"+ new_dtexpS.get('month')+"-" + new_dtexpS.get('day') +" "+ new_dtexpS.get('hour'), "exp: (+/-)2023-12-31 12");`
env
lutz@lutz-HONOR:~/mqtt$ node moment_env.js
Sun Oct 15 2023 15:57:59 GMT+0200 (Central European Summer Time)
10/15/2023, 3:57:59 PM
-120
2.29.4
lutz@lutz-HONOR:~/mqtt$ node -v
v20.8.1
Additional context
as you see, daysjs get it wrong too, but differently.
sorry, my fault, adding 12m 31d is of course adding 1 y, 1m (,1d), not 1y!
that leaves less complaints, I will raise new issue.