How to get next MonthDay (next Christmas) with java 8 time API?

怎甘沉沦 提交于 2019-12-21 21:33:15

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!