Despite all the previous answers, I still had to dig around to work out what Java8 was doing, so here is what I found to be the most intuitive way of doing it:
LocalDate implements Temporal
with(TemporalField field, long newValue)
Returns an object of the same type as this object with the specified field altered.
So we have to tell it which date part of LocalDate
we want to change (DAY_OF_WEEK
) and change to what value.
In case you had doubts that the days in the week might be counted from 0 to 6 or from 1 to 7:
System.out.printf("first day of week (0 or 1) == %d \n",
ChronoField.DAY_OF_WEEK.range().getMinimum());
first day of week (0 or 1) == 1
I had to nail down what my JDK was providing for defaults - YMMV:
System.out.printf("default zone offset==[%s]\n",
ZoneId.systemDefault());
System.out.printf("1st day of week==%s\n",
WeekFields.of(Locale.getDefault()).getFirstDayOfWeek());
default zone offset==[Europe/London]
1st day of week==MONDAY
So if I execute some code based on these defaults, like so:
LocalDate localDate = LocalDate.now();
System.out.printf("localDate == %s \n", localDate);
System.out.printf("localdate first day of week == %s (%s) \n",
localDate.with(ChronoField.DAY_OF_WEEK, 1),
localDate.with(ChronoField.DAY_OF_WEEK, 1).getDayOfWeek());
localDate == 2017-10-24
localdate first day of week == 2017-10-23 (MONDAY)
then Java goes with ChronoField.DAY_OF_WEEK
which not only defines which part of the date we want to alter, but also how to alter it.
So if we want our code to deal with whatever the user specifies as the first day of the week, we create our own definition of how week-based calculations are meant to be done, using the WeekFields.of()
factory method.
Using this we can pass in our own dayOfWeek
parameter to with()
to do the date calculation the way we want:
TemporalField myWeek = WeekFields.of(DayOfWeek.SUNDAY, 1).dayOfWeek();
System.out.printf("configured localdate first day of week == %s (%s) \n",
localDate.with(myWeek, 1),
localDate.with(myWeek, 1).getDayOfWeek());
configured localdate first day of week == 2017-10-22 (SUNDAY)
For more insight, have a look at the code in LocalDate.with()
, it's quite interesting.