Reputation: 85
I would like to convert a YearMonth
to a LocalDate
with the specified DayOfWeek
, e.g. the second Tuesday of February 2019.
The following code throws a DateTimeException
:
YearMonth yearMonth = YearMonth.of(2019, Month.FEBRUARY);
TemporalAdjuster secondTuesday = TemporalAdjusters.dayOfWeekInMonth(2, DayOfWeek.TUESDAY);
LocalDate date = LocalDate.from(yearMonth).with(secondTuesday);
In order to make my code work I need to replace the last line with
LocalDate date = yearMonth.atDay(1).with(secondTuesday);
Isn't there a cleaner solution that doesn't require the use of atDay(1)
?
Upvotes: 3
Views: 6458
Reputation: 86203
You have found the best and cleanest (or the least poor) solution yourself already:
LocalDate date = yearMonth.atDay(1).with(secondTuesday);
The argument to atDay
doesn’t necessarily need to be 1, but it needs to be a valid day of the month in question, so why not 1?
with()
always returns the same type you called it on. That is, YearMonth.with()
will always return a YearMonth
, never a LocalDate
. Therefore you cannot use your adjuster there.
I understand and share your objection, but what you’ve got already is the best we can do. You can and should probably wrap it inside a method with a nice name.
Upvotes: 7
Reputation: 638
I believe that your code is almost done. The important point is for use the TemporalAdjusters.dayOfWeekInMonth() method you need to provide a LocalDate with day.
Your example is right, but if you want to be little bit more clear, you can change for:
TemporalAdjuster secondTuesday = TemporalAdjusters.dayOfWeekInMonth(2, DayOfWeek.TUESDAY);
LocalDate dateLocalDate = LocalDate.of(2019, Month.FEBRUARY, 1).with(secondTuesday);
And put this code into a method, like this:
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);
}
Here you can find the documentation about this method: TemporalAdjusters Docs
Upvotes: 0