Ily*_*lya 8 period date-difference kotlin java-time localdate
我有两个LocalDate
声明如下:
val startDate = LocalDate.of(2019, 10, 31) // 2019-10-31
val endDate = LocalDate.of(2019, 9, 30) // 2019-09-30
Run Code Online (Sandbox Code Playgroud)
然后我使用Period.between
函数计算它们之间的周期:
val period = Period.between(startDate, endDate) // P-1M-1D
Run Code Online (Sandbox Code Playgroud)
此处的期间为负数的月份和天数,如果endDate
早于,则可以预期startDate
。
但是,当我将其添加period
回时startDate
,得到的结果不是endDate
,而是前一天的日期:
val endDate1 = startDate.plus(period) // 2019-09-29
Run Code Online (Sandbox Code Playgroud)
所以问题是,为什么不不变
startDate.plus(Period.between(startDate, endDate)) == endDate
保留这两个日期?
是Period.between
谁返回了不正确的期限,还是LocalDate.plus
谁添加了不正确的期限?
如果您看如何plus
实现LocalDate
@Override
public LocalDate plus(TemporalAmount amountToAdd) {
if (amountToAdd instanceof Period) {
Period periodToAdd = (Period) amountToAdd;
return plusMonths(periodToAdd.toTotalMonths()).plusDays(periodToAdd.getDays());
}
...
}
Run Code Online (Sandbox Code Playgroud)
你会看到plusMonths(...)
和plusDays(...)
那里。
plusMonths
处理一个月有31天,另一个有30天的情况。因此,将输出以下代码,2019-09-30
而不是不存在的代码2019-09-31
println(startDate.plusMonths(period.months.toLong()))
Run Code Online (Sandbox Code Playgroud)
之后,减去一天将得出2019-09-29
。这是正确的结果,因为2019-09-29
和2019-10-31
相隔1个月1天
该Period.between
计算是奇怪,在这种情况下,可以归结为
LocalDate end = LocalDate.from(endDateExclusive);
long totalMonths = end.getProlepticMonth() - this.getProlepticMonth();
int days = end.day - this.day;
long years = totalMonths / 12;
int months = (int) (totalMonths % 12); // safe
return Period.of(Math.toIntExact(years), months, days);
Run Code Online (Sandbox Code Playgroud)
其中getProlepticMonth
是从00-00-00的月份总数。在这种情况下,是1个月零1天。
从我的理解,这是一个错误Period.between
,并LocalDate#plus
为正负周期的互动,因为下面的代码具有相同的含义
val startDate = LocalDate.of(2019, 10, 31)
val endDate = LocalDate.of(2019, 9, 30)
val period = Period.between(endDate, startDate)
println(endDate.plus(period))
Run Code Online (Sandbox Code Playgroud)
但是它打印正确2019-10-31
。
问题在于LocalDate#plusMonths
归一化日期总是“正确的”。在下面的代码中,您可以看到从2019-10-31
结果中减去1个月后2019-09-31
,将其标准化为2019-10-30
public LocalDate plusMonths(long monthsToAdd) {
...
return resolvePreviousValid(newYear, newMonth, day);
}
private static LocalDate resolvePreviousValid(int year, int month, int day) {
switch (month) {
...
case 9:
case 11:
day = Math.min(day, 30);
break;
}
return new LocalDate(year, month, day);
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
194 次 |
最近记录: |