问题
Let's say I want to know how many days are until Christmas with a method that works any day of any year so next Christmas may be this year or next year that I don't know if it is a leap year or not.
I might calculate the next Christmas date and then calculate the days from now until then. I can represent Christmas Day as MonthDay.of(12, 25) but I can't find how that helps.
I found it is easy to calculate the date of next Monday this way:
ZonedDateTime nextMonday = ZonedDateTime.now()
.with(TemporalAdjusters.next(DayOfWeek.MONDAY))
.truncatedTo(ChronoUnit.DAYS);
But I can't find any TemporalAdjuster to do the same with MonthDay.
Is there an easy way I didn't find?
回答1:
I don't think there is a built-in temporal adjuster to go to the next "MonthDay" but you can build it yourself:
public static void main(String[] args) {
MonthDay XMas = MonthDay.of(DECEMBER, 25);
System.out.println(LocalDate.of(2014, DECEMBER, 5).with(nextMonthDay(XMas)));
System.out.println(LocalDate.of(2014, DECEMBER, 26).with(nextMonthDay(XMas)));
}
public static TemporalAdjuster nextMonthDay(MonthDay monthDay) {
return (temporal) -> {
int day = temporal.get(DAY_OF_MONTH);
int month = temporal.get(MONTH_OF_YEAR);
int targetDay = monthDay.getDayOfMonth();
int targetMonth = monthDay.getMonthValue();
return MonthDay.of(month, day).isBefore(monthDay)
? temporal.with(MONTH_OF_YEAR, targetMonth).with(DAY_OF_MONTH, targetDay)
: temporal.with(MONTH_OF_YEAR, targetMonth).with(DAY_OF_MONTH, targetDay).plus(1, YEARS);
}
回答2:
I am using the following temporal adjusters:
public static TemporalAdjuster nextOrSame(MonthDay monthDay) {
return temporal -> monthDay.adjustInto(temporal).plus(MonthDay.from(temporal).compareTo(monthDay) > 0 ? 1 : 0, YEARS);
}
public static TemporalAdjuster previousOrSame(MonthDay monthDay) {
return temporal -> monthDay.adjustInto(temporal).minus(MonthDay.from(temporal).compareTo(monthDay) < 0 ? 1 : 0, YEARS);
}
回答3:
Here is a method that creates a temporal adjuster given a MonthDay, just like the one of assylias but code is different. I think both work.
private static TemporalAdjuster nextMonthDayAdjuster(final MonthDay md) {
return (Temporal d) -> {
Function<Integer, Temporal> dateOnYear = year -> md.atYear(year).adjustInto(d);
int year = d.get(ChronoField.YEAR);
Temporal dateThatYear = dateOnYear.apply(year);
if (d.until(dateThatYear, ChronoUnit.NANOS) > 0L) {
return dateThatYear;
} else {
return dateOnYear.apply(year + 1);
}
};
}
来源:https://stackoverflow.com/questions/30215819/how-to-get-next-monthday-next-christmas-with-java-8-time-api