I have date time strings with the following format: YYYY-MM-DD HH:MM:SS.SSSSSS
For example:
const d1 = '2022-07-03 03:45:15.679570'
const d2 = '2022-07-03 03:45:15.679638'
What I'd like to achieve is the ability to subtract these date times, e.g. in the above example the result would be:
console.log(subtractDates(d1, d2)) // -0000-00-00 00-00-00.000068
console.log(subtractDates(d2, d1)) // 0000-00-00 00-00-00.000068
I was looking for different libraries but they all have resolution of 0-999 ms and that's it.
CodePudding user response:
The subtraction of dates becomes ambiguous when months are subtracted. For instance, there are several possibilities on how to represent the difference between 2022-03-31 and 2022-02-28. If this is considered to be a difference of 1 months and 3 days, then what if we add one day to both dates? Is then the difference (of the same number of days) suddenly an exact month?
To avoid this ambiguity, I would suggest to express the difference in a number of days (and smaller units of time) even when that number of days exceeds a month or even a year. Just keep the greatest unit of measure to the day when dealing with durations.
Here is a pair of classes that could easily be extended to provide more functionality. The general idea is to use the numeric system of the native Date
type, but to multiply it by 1000.
class MicroDuration {
constructor(us) {
this.us = Math.abs(us); // Don't work with negative durations.
}
toString() { // dddddd hh:mm:ss.ssssss
return (Math.floor(this.us / 86_400_000_000) " "
new Date(Math.floor(this.us / 1000)).toJSON().slice(11, 23)
(this.us % 1000 "").padStart(3, "0")
).padStart(22, "0");
}
}
class MicroDate {
constructor(iso) {
iso = iso.replace(" ", "T").replace(/\d$/, "$&Z");
this.us = Date.parse(iso) * 1000 parseInt(iso.slice(-4));
}
diff(arg) {
if (!(arg instanceof MicroDate)) arg = new MicroDate(arg);
return new MicroDuration(this.us - arg.us);
}
toString() {
return new Date(Math.floor(this.us / 1000)).toJSON()
.replace("Z", (this.us % 1000 "").padStart(3, "0"))
.replace("T", " ");
}
}
// Demo
const d1 = '2022-07-03 03:45:15.679570'
const d2 = '2024-08-03 15:45:15.678638'
const diff = new MicroDate(d1).diff(d2).toString();
console.log(diff);