我想显示两个日期时间之间的持续时间,但我发现了一个不确定为什么不起作用的情况。我目前正在使用date-fns
,我也尝试过luxon
,它给了我相同的结果。
代码片段
import { intervalToDuration as intervalToDurationDateFns } from 'date-fns';
import { DateTime } from "luxon";
function intervalToDurationLuxon({ start, end }) {
const startDate = DateTime.fromJSDate(start);
const endDate = DateTime.fromJSDate(end);
const i = startDate.until(endDate);
return i.toDuration(['years', 'months', 'days', 'hours', 'minutes', 'seconds']).toObject();
}
const target = new Date(2023, 2, 1, 23, 59, 59, 999);
const beforeMiddleOfNight = new Date(2022, 8, 29, 23, 59, 59, 99);
const afterMiddleOfNight = new Date(2022, 8, 30, 0, 0, 0, 0);
console.log('date-fns')
console.log(intervalToDurationDateFns({ start: beforeMiddleOfNight, end: target }));
console.log(intervalToDurationDateFns({ start: afterMiddleOfNight, end: target }));
console.log('luxon')
console.log(intervalToDurationLuxon({ start: beforeMiddleOfNight, end: target }));
console.log(intervalToDurationLuxon({ start: afterMiddleOfNight, end: target }));
实际输出
date-fns
{years: 0, months: 5, days: 1, hours: 0, minutes: 0, seconds: 0}
{years: 0, months: 5, days: 1, hours: 23, minutes: 59, seconds: 59}
luxon
{years: 0, months: 5, days: 1, hours: 0, minutes: 0, seconds: 0.9}
{years: 0, months: 5, days: 1, hours: 23, minutes: 59, seconds: 59.999}
预期输出
date-fns
{years: 0, months: 5, days: 2, hours: 0, minutes: 0, seconds: 0}
{years: 0, months: 5, days: 1, hours: 23, minutes: 59, seconds: 59}
luxon
{years: 0, months: 5, days: 2, hours: 0, minutes: 0, seconds: 0.9}
{years: 0, months: 5, days: 1, hours: 23, minutes: 59, seconds: 59.999}
我发现,只有当 33月28日我不明白为什么在这种情况下天数计算错误。 有人能解释一下为什么会发生这种事吗? 有没有更好的解决方案可以涵盖我找不到的其他场景?start
是一个月的最后一天(28、29、30或31(,并且end
在3月1日和
只有当开始时间为一个月的最后一天(28、29、30或31(,结束时间为3月1日至3月28日时,才会发生这种情况。
原因是二月只有28天,而以月计算是不精确的。
当你在一个月的结束时(28日、29日、30日或31日(,再加上几个月,你就会在2月到达,你总是会在2月底结束,即28日。以月为单位计算,所有这些间隔都有相同的持续时间,无论它们是从哪一天开始的。";余数";然后计算为您必须添加到2月28日才能在3月到达所需日期时间的天数、小时数等。
这不仅适用于3月结束的间隔,也适用于所有月份:如果该月的结束日期小于该月的开始日期,但该月的起始日期大于该月结束日期之前的天数,则忽略剩余天数。
另请参阅有关Duration
数学的文档。