来自 YearMonth 的 LocalDate 和第 n 个 DayOfWeek

LocalDate from YearMonth with nth DayOfWeek

我想将 YearMonth 转换为具有指定 DayOfWeekLocalDate,例如2019 年 2 月的第二个星期二。

以下代码抛出 DateTimeException:

YearMonth yearMonth = YearMonth.of(2019, Month.FEBRUARY);
TemporalAdjuster secondTuesday = TemporalAdjusters.dayOfWeekInMonth(2, DayOfWeek.TUESDAY);

LocalDate date = LocalDate.from(yearMonth).with(secondTuesday);

为了使我的代码正常工作,我需要将最后一行替换为

LocalDate date = yearMonth.atDay(1).with(secondTuesday);

是否有不需要使用 atDay(1) 的更清洁的解决方案?

我相信你的代码已经差不多完成了。重点是要使用 TemporalAdjusters.dayOfWeekInMonth() 方法,您需要提供带日期的 LocalDate。

你的例子是正确的,但如果你想更清楚一点,你可以更改为:

TemporalAdjuster secondTuesday = TemporalAdjusters.dayOfWeekInMonth(2, DayOfWeek.TUESDAY);
LocalDate dateLocalDate = LocalDate.of(2019, Month.FEBRUARY, 1).with(secondTuesday);

并将这段代码放入一个方法中,如下所示:

public static void main(String[] args) {
    LocalDate localDate = getLocalDateByDayOfWeek(2019, Month.FEBRUARY, 2, DayOfWeek.TUESDAY);
    System.out.println(localDate);
}

private static LocalDate getLocalDateByDayOfWeek(int year, Month month, int weekNumber, DayOfWeek dayOfWeek) {
    TemporalAdjuster temporalWeek = TemporalAdjusters.dayOfWeekInMonth(weekNumber, dayOfWeek);
    return LocalDate.of(year, month, 1).with(temporalWeek);
}

在这里你可以找到关于这个方法的文档:TemporalAdjusters Docs

您已经自己找到了最好、最干净(或最不差)的解决方案:

LocalDate date = yearMonth.atDay(1).with(secondTuesday);

atDay 的参数不一定必须是 1,但它必须是相关月份的有效日期,为什么不是 1?

with() 始终 return 与您调用它的类型相同。也就是说,YearMonth.with() 总是 return 一个 YearMonth,永远不会是一个 LocalDate。因此你不能在那里使用你的调节器。

我理解并同意你的异议,但你已经得到的是我们能做的最好的。您可以而且应该将它包装在一个名称好听的方法中。