Dan*_*ore 18 java java-8 off-by-one localdate
Java的LocalDate API似乎在plus(...)用long 调用时给出了错误的答案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
}
}
Run Code Online (Sandbox Code Playgroud)
ass*_*ias 21
A Period由数年,数月和数天组成。您的情况Period.between(birthA, eventA)是26年7个月12天。
如果将其添加到中birthA,则会得到:
哪个按预期工作。
If you apply the same calculation, starting from May 9, 1992, you get December 21, 2018.
If you want to add a certain number of days instead, you can't simply add the period (as years and months don't always have the same length). One option is to use ChonoUnit.DAYS.between instead:
LocalDate halfA = eventA.plusDays(ChronoUnit.DAYS.between(birthA, eventA));
Run Code Online (Sandbox Code Playgroud)
That returns 2018-12-20 which I think is what you expected.
To complement assylias' answer, here is a simplified example to show why this happens:
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
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
355 次 |
| 最近记录: |