Get the date of the first day of the week based on LocalDate.now () in Java 8

I would like to get the date of the first day of the week based on LocalDate.now (). The following was possible in JodaTime, but it seems to have been removed from the new date API in Java 8.

LocalDate now = LocalDate.now(); System.out.println(now.withDayOfWeek(DateTimeConstants.MONDAY)); 

I cannot call 'withDayOfWeek ()' because it does not exist.

So my question is: How to get the date of the first day of the week based on some LocalDate?

+40
java java-8
source share
9 answers

Please note that the expression System.out.println(now.with(DayOfWeek.MONDAY)) is language-independent, as it uses ISO-8601, so it always jumps back on the last Monday (or stays on Monday when date indicates Monday).

In the USA as well as in some other countries where the week starts on Sunday, it may not work as you expected - now.with(DayOfWeek.MONDAY) will not move forward on Monday, if the date indicates Sunday.

If you need to solve these problems, it is better to use the localized field WeekFields.dayOfWeek () :

 LocalDate now = LocalDate.now(); TemporalField fieldISO = WeekFields.of(Locale.FRANCE).dayOfWeek(); System.out.println(now.with(fieldISO, 1)); // 2015-02-09 (Monday) TemporalField fieldUS = WeekFields.of(Locale.US).dayOfWeek(); System.out.println(now.with(fieldUS, 1)); // 2015-02-08 (Sunday) 

Another example due to the comments below:

 LocalDate ld = LocalDate.of(2017, 8, 18); // Friday as original date System.out.println( ld.with(DayOfWeek.SUNDAY)); // 2017-08-20 (2 days later according to ISO) // Now let again set the date to Sunday, but this time in a localized way... // the method dayOfWeek() uses localized numbering (Sunday = 1 in US and = 7 in France) System.out.println(ld.with(WeekFields.of(Locale.US).dayOfWeek(), 1L)); // 2017-08-13 System.out.println(ld.with(WeekFields.of(Locale.FRANCE).dayOfWeek(), 7L)); // 2017-08-20 

An example in the USA gives a fairly clear idea of ​​what someone living in the USA will wait until the last, not the next Sunday, because Sunday is considered the first day of the week in the USA. A simple ISO-based expression with(DayOfWeek.SUNDAY) ignores this localization problem.

+66
source share

Try

 System.out.println(now.with(DayOfWeek.MONDAY)); 
+17
source share

Despite all the previous answers, I still had to dig around to figure out what Java8 was doing, so here is what I found the most intuitive way to do this:

LocalDate implements Temporal

with(TemporalField field, long newValue)

Returns an object of the same type as this object, with the specified modified field.

Therefore, we must tell him what part of the LocalDate date we want to change ( DAY_OF_WEEK ) and change to what value.

If in doubt, the days of the week can 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 commit what my JDK provided by default - 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 

Therefore, if I execute some code based on these default values, like this:

  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 uses ChronoField.DAY_OF_WEEK which not only determines which part of the date we want to change, but also how to change it.

Therefore, if we want our code to work with what the user specifies as the first day of the week, we will create our own definition of how week-based calculations should be performed using the factory method WeekFields.of() .

Using this, we can pass our own dayOfWeek parameter to with() to calculate the date 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 a deeper understanding, take a look at the code in LocalDate.with() , it is quite interesting.

+5
source share

Thanks came from this question .

 Calendar cal = Calendar.getInstance(); cal.set(Calendar.HOUR_OF_DAY, 0); // ! clear would not reset the hour of day ! cal.clear(Calendar.MINUTE); cal.clear(Calendar.SECOND); cal.clear(Calendar.MILLISECOND); // get start of this week in milliseconds cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek()); System.out.println("Start of this week: " + cal.getTime()); System.out.println("... in milliseconds: " + cal.getTimeInMillis()); 
+2
source share

As the correct answer from Ray says, you can call with and pass the DayOfWeek listing.

Timezone

Please note that the time zone is critical for determining the date for today. At any time, the date depends on where you are on the globe.

 ZoneId zoneId = ZoneId.of ( "America/Montreal" ); LocalDate firstDayOfThisWeek = LocalDate.now ( zoneId ).with ( DayOfWeek.MONDAY ); 

If you do not specify a time zone, the current JVMs time zone is used by default. Beware: this default value may change at any time during runtime! It is better to indicate your desired / expected time zone .

ZonedDateTime

You can apply the time zone ( ZoneId ) to LocalDate to get a ZonedDateTime representing the first moment of the week.

 ZonedDateTime thisWeekStart = firstDayOfThisWeek.atStartOfDay ( zoneId ); 
+1
source share

LocalDate doesn't seem to have this, but WeekFields (which from the java-8 API) does ( here ). So you can do this:

 WeekFields.of(Locale.getDefault()).firstDayOfWeek.value 

This returns the value of the first day of the week, starting from 1 on Monday, ending with 7 on Sunday.

Usage example (in Kotlin) to get the new LocalDate that should be set by dayOfWeek, go back in time, not forward:

 /**@param targetDayOfWeek day of week to go to, starting from 1 as Monday (and 7 is Sunday) */ fun LocalDate.minusDaysToDayOfWeek(targetDayOfWeek: Int = WeekFields.of(Locale.getDefault()).firstDayOfWeek.value): LocalDate { //conversion so that Sunday is 0, Monday is 1, etc: val diffDays = (dayOfWeek.value % 7) - (targetDayOfWeek % 7) val result = when { diffDays == 0 -> this diffDays < 0 -> minusDays((7 + diffDays).toLong()) else -> minusDays(diffDays.toLong()) } return result } 

Examples of inputs and outputs:

 2017-12-31 -> 2017-12-31 2018-01-01 -> 2017-12-31 2018-01-02 -> 2017-12-31 2018-01-03 -> 2017-12-31 2018-01-04 -> 2017-12-31 2018-01-05 -> 2017-12-31 2018-01-06 -> 2017-12-31 2018-01-07 -> 2018-01-07 2018-01-08 -> 2018-01-07 2018-01-09 -> 2018-01-07 2018-01-10 -> 2018-01-07 2018-01-11 -> 2018-01-07 2018-01-12 -> 2018-01-07 2018-01-13 -> 2018-01-07 2018-01-14 -> 2018-01-14 2018-01-15 -> 2018-01-14 

And here is an example function for moving forward to the target day of the week:

 fun LocalDate.plusDaysToDayOfWeek(targetDayOfWeek: Int = getLastDayOfWeek()): LocalDate { val diffDays = (targetDayOfWeek % 7) - (dayOfWeek.value % 7) val result = when { diffDays == 0 -> this diffDays < 0 -> plusDays((7 + diffDays).toLong()) else -> plusDays(diffDays.toLong()) } return result } /**@return the last day of week, when 1 is Monday ... 7 is Sunday) */ @JvmStatic fun getLastDayOfWeek(firstDayOfWeek: DayOfWeek = WeekFields.of(Locale.getDefault()).firstDayOfWeek): Int { return when (firstDayOfWeek) { DayOfWeek.MONDAY -> DayOfWeek.SUNDAY.value else -> firstDayOfWeek.value - 1 } } 

By the way, it is strange that I think that the code behind the scenes of the new API actually uses the Calendar class ...

If you hate using dayOfWeek used for LocalDate (like me), and you prefer the one used with Calendar, you can use these simple converters:

 fun DayOfWeek.toCalendarDayOfWeek(): Int { return when (this) { DayOfWeek.SATURDAY -> Calendar.SATURDAY else -> (this.value + 1) % 7 } } @JvmStatic fun convertLocalDateDayOfWeekToCalendarDayOfWeek(localDateDayOfWeek: Int): Int { return when (localDateDayOfWeek) { DayOfWeek.SATURDAY.value -> Calendar.SATURDAY else -> (localDateDayOfWeek + 1) % 7 } } @JvmStatic fun convertFromCalendarDayOfWeekToLocalDateDayOfWeek(calendarDayOfWeek: Int): Int { return when (calendarDayOfWeek) { Calendar.SUNDAY -> DayOfWeek.SUNDAY.value else -> calendarDayOfWeek - 1 } } 
+1
source share

This works for me if I want Monday to be the first day of the current week:

 LocalDate mondayDate = LocalDate.now().with(WeekFields.of(Locale.FRANCE).getFirstDayOfWeek()); 
+1
source share

With Joda Time, what do you think of

 now.toString("EEEE", locale) 
0
source share
 public void getWeekFromADateOfAMonth(){ String date = "2019-01-02T18:25:43.511Z"; TemporalField fieldISO = WeekFields.of(Locale.US).dayOfWeek(); ZonedDateTime dateTime = ZonedDateTime.parse(date); int week = dateTime.get ( IsoFields.WEEK_OF_WEEK_BASED_YEAR ); int weekYear = dateTime.get ( IsoFields.WEEK_BASED_YEAR ); System.out.println ( "now: " + dateTime + " is week: " + week + " of weekYear: " + weekYear ); int startDate = dateTime.with(fieldISO,1).getDayOfMonth(); int endDate = dateTime.with(fieldISO,7).getDayOfMonth(); String startMonth = String.valueOf(dateTime.with(fieldISO,1).getMonth()); String endMonth = String.valueOf(dateTime.with(fieldISO,7).getMonth()); } 
0
source share

All Articles