我認爲OP發現了最後的解決方案仍然不正確的,因爲我們在ISO週日期的情況下移動,而不是普通的日曆日期。因此,表達式LocalDate.of(date.getYear() + 1, 1, 7)
在年邊界附近經常是錯誤的(參見示例方法lastWeekOfYearOld(...)
)。相反,我們必須添加一個以星期爲單位的年份,而不是一個日曆年(限於1月 - 12月),現在已經在第二個方法lastWeekOfYearCorrect(...)
中使用了。我也顯示基礎上,周的年字段的上下文敏感值範圍另一個正確的選擇(參見方法lastWeekOfYearAlternative(...)
。
public static void main(String[] args) {
System.out.println(
lastWeekOfYearOld(LocalDate.of(2015, 12, 31))); // 2015-12-28 (OK)
System.out.println(
lastWeekOfYearOld(LocalDate.of(2016, 1, 1))); // 2016-12-26 (Wrong)
System.out.println(
lastWeekOfYearCorrect(LocalDate.of(2015, 12, 31))); // 2015-12-28 (OK)
System.out.println(
lastWeekOfYearCorrect(LocalDate.of(2016, 1, 1))); // 2015-12-28 (OK)
System.out.println(
lastWeekOfYearAlternative(LocalDate.of(2015, 12, 31))); // 2015-12-28 (OK)
System.out.println(
lastWeekOfYearAlternative(LocalDate.of(2016, 1, 1))); // 2015-12-28 (OK)
}
private static LocalDate lastWeekOfYearOld(LocalDate date) {
return LocalDate.of(date.getYear() + 1, 1, 7)
.with(WeekFields.ISO.weekOfWeekBasedYear(), 1)
.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)).minusWeeks(1);
}
private static LocalDate lastWeekOfYearCorrect(LocalDate date) {
date =
date.plus(1, IsoFields.WEEK_BASED_YEARS)
.with(DayOfWeek.MONDAY)
.with(WeekFields.ISO.weekOfWeekBasedYear(), 1);
return date.minusWeeks(1);
}
private static LocalDate lastWeekOfYearAlternative(LocalDate date) {
TemporalField woyField = WeekFields.ISO.weekOfWeekBasedYear();
date = date.with(woyField, woyField.rangeRefinedBy(date).getMaximum());
return date.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
}
看起來不錯給我,雖然我可能會使用'minusWeeks(1) ''而不是'minusDays(7)',並且放在一個新的行上,你可能會爲'lastWeekOfWeekYear'編寫自己的'TemporalAdjuster' –
另一種方式(不一定更具可讀性)是'date.with(lastDayOfYear() ).minusDays(7 - WeekFields.ISO.getMinimalDaysInFirstWeek())。with(previousOrSame(MONDAY))' – assylias
@Oxolotl我建議您提取您的建議解決方案,並將其作爲答案發布。您可以稍後接受它以標記問題as closed。完美的回答你自己的問題堆棧溢出 –