在某些情况下,
ChronoUnit.MONTHS
对日期执行数学计算不一致,具体取决于我们是加还是减。极端情况是当我们例如为日期添加 1 个月2023-01-31
。我知道如果结果应该是 2023-02-28
或 2023-03-01
,则没有单一正确的答案。然而,我希望相同的 API 至少使用相同的假设,但这里的情况并非如此:
var d1 = OffsetDateTime.parse("2023-01-31T10:00:00Z");
// add 1 month
var d2 = ChronoUnit.MONTHS.addTo(d1, 1);
// add 23 hours
d2 = ChronoUnit.HOURS.addTo(d2, 23);
// subtract
System.out.println(ChronoUnit.MONTHS.between(d1, d2)); // 0
显然,
addTo()
假设从 2023-01-31 10:00
开始的 1 个月是 2023-02-28 10:00
,但是,between()
假设一整月于 2023-03-01 10:00
结束。
这是一个错误吗?我是否错过或误解了什么?
顺便说一句,
d1.plusMonths(1)
的工作方式与 addTo()
相同,而且这种行为甚至有明确的记录。 between()
好像和其他操作不一致。
这不是一个错误。 记录如下:
计算返回一个整数,代表的数量 两个时间之间的完整单位。例如,金额为 11:30 到 13:29 之间的时间将仅为一小时 两小时还差一分钟。
在以下代码中,d2 变为 2023-02-28T10:00Z 但当它根据上述文档计算差异时,如果日期如 2023-02-31T10:00 ,它会将差异计为 1 :00Z 存在。如果不是,则第二天将差值计为 1,即 2023-03-01T10:00:00Z。
var d1 = OffsetDateTime.parse("2023-01-31T10:00:00Z");
var d2 = ChronoUnit.MONTHS.addTo(d1, 1);
System.out.println(ChronoUnit.MONTHS.between(d1, d2)); // 0
当您在下一个语句中添加 23 小时时,它会变成 2023-03-01T09:00Z,比 2023-03-01T10:00:00Z 少一小时;因此还没有达到将差异算作1个月的程度。
d2 = ChronoUnit.HOURS.addTo(d2, 23); // 2023-03-01T09:00Z
如果添加 24 小时,它就会变成 2023-03-01T10:00:00Z 并给你差值 1。
此行为在所有时间单位中都是一致的。