LocalDate.plus 不正确的答案

2022-09-02 20:59:44

Java的LocalDate API似乎在调用长时给出了不正确的答案,其中我得到了一个错误。我在这里做错了什么吗?plus(...)Period

import java.time.LocalDate;
import java.time.Month;
import java.time.Period;
import java.time.temporal.ChronoUnit;

public class Main
{
    public static void main(String[] args)
    {
        // Long Period
        LocalDate birthA = LocalDate.of(1965, Month.SEPTEMBER, 27);
        LocalDate eventA = LocalDate.of(1992, Month.MAY, 9);
        LocalDate halfA = eventA.plus(Period.between(birthA, eventA));
        System.out.println(halfA); // 2018-12-21 ????
        System.out.println(ChronoUnit.DAYS.between(birthA, eventA)); // 9721
        System.out.println(ChronoUnit.DAYS.between(eventA, halfA)); // 9722 ????

        // Short Period
        LocalDate birthB = LocalDate.of(2012, Month.SEPTEMBER, 10);
        LocalDate eventB = LocalDate.of(2012, Month.SEPTEMBER, 12);
        LocalDate halfB = eventB.plus(Period.between(birthB, eventB));
        System.out.println(halfB); // 2018-09-14
        System.out.println(ChronoUnit.DAYS.between(birthB, eventB)); // 2
        System.out.println(ChronoUnit.DAYS.between(eventB, halfB)); // 2
    }
}

答案 1

A由数年,月和日组成。在你的情况下,是26年7个月零12天。PeriodPeriod.between(birthA, eventA)

如果将其添加到 ,您将获得:birthA

  • 1965 + 26岁 -> 1991
  • 1991年9月+7个月-1991年4月>日
  • 1991年4月27日+12天-> 1992年5月9日

它按预期工作。

如果应用相同的计算,从 1992 年 5 月 9 日开始,您将获得 2018 年 12 月 21 日。

如果要添加一定数量的天数,则不能简单地添加时间段(因为年份和月份并不总是具有相同的长度)。一种选择是改用:ChonoUnit.DAYS.between

LocalDate halfA = eventA.plusDays(ChronoUnit.DAYS.between(birthA, eventA));

这种回报,我认为这是你所期望的。2018-12-20


答案 2

为了补充assylias的答案,这里有一个简化的例子来说明为什么会发生这种情况:

    public static void main(String[] args)
    {
        LocalDate a = LocalDate.of(1992, Month.APRIL, 1);
        LocalDate b = LocalDate.of(1992, Month.MAY, 1);
        // Calculate the period. It will return "One month"
        Period period = Period.between(a, b);
        // Add one month to b. It will return June 1, 1992
        LocalDate c = b.plus(period);
        System.out.println(ChronoUnit.DAYS.between(a, b)); // 30 days as April has 30 days
        System.out.println(ChronoUnit.DAYS.between(b, c)); // 31 days as May has 31 days
    }

推荐