LocalDate.plus 答案不正确
LocalDate.plus Incorrect Answer
Java 的 LocalDate API 在用长 Period
调用 plus(...)
时似乎给出了错误的答案,我得到了一个错误。我是不是做错了什么?
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
}
}
一个Period
由若干年、月、日组成。在你的例子中,Period.between(birthA, eventA)
是 26 年 7 个月零 12 天。
如果将其添加到 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));
那个 returns 2018-12-20
我认为是你所期望的。
为了补充 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
}
Java 的 LocalDate API 在用长 Period
调用 plus(...)
时似乎给出了错误的答案,我得到了一个错误。我是不是做错了什么?
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
}
}
一个Period
由若干年、月、日组成。在你的例子中,Period.between(birthA, eventA)
是 26 年 7 个月零 12 天。
如果将其添加到 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));
那个 returns 2018-12-20
我认为是你所期望的。
为了补充 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
}