moment / moment

Parse, validate, manipulate, and display dates in javascript.

Home Page:momentjs.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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.

  1. years before BC (negative years) do not work at all.
  2. durations do not include leapdays (the doc mentions this, but should it not include leapdays?, maybe new function?)
  3. 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.