-1

I'm trying to get a date with a Month number, week of month number and a day of week number I thought this will be easy and did this:

LocalDate nextbookingDate = LocalDate.now().plusYears(1);
nextBookingDate = nextBookingDate.with(Month.of(1));
nextBookingDate = nextBookingDate.with(WeekFields.ISO.weekOfMonth(), 1);
nextBookingDate = nextBookingDate.with(DayOfWeek.of(1));
System.out.println(nextBookingDate); //2019-12-30

nextBookingDateshould be 2020-01-06 because its the first Monday in January.
But why do I get 2019-12-30 and how do I solve this?

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
Leon
  • 5
  • 5

2 Answers2

2

In each new line, you are overwriting what you have done in the previous line. Try something like this:

nextBookingDate = now()
   .with(Month.of(1))
   .with(WeekFields.ISO.weekOfMonth(), 1)
   .with(DayOfWeek.of(1));

but be aware that December 30, 2019 is actually the first day of week 1 of 2020.

Because the question has been updated, a more relevant answer would be:

LocalDate nextBookingDate = LocalDate.now().plusYears(1)
   .with(Month.JANUARY)
   .with(TemporalAdjusters.dayOfWeekInMonth(1, DayOfWeek.MONDAY));

and you can replace the 1 as argument for dayOfWeekInMonth with a number from 2 through 5 as appropriate.

NorthernSky
  • 488
  • 2
  • 10
  • Yes i figured that out after more than one hour :D But how do i get the first monday in January then? – Leon Dec 08 '19 at 13:54
  • 1
    Look into TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY), after first creating a LocalDate in January of the relevant year. – NorthernSky Dec 08 '19 at 13:57
  • Yes but the first monday was just for example, what if i want the second monday in january or the third? – Leon Dec 08 '19 at 14:00
  • 2
    Then you can use TemporalAdjusters.dayOfWeekInMonth with 2 or 3 as the 'ordinal' parameter. – NorthernSky Dec 08 '19 at 14:02
  • @NorthernSky You are completely correct, and iit’s a good observation. I took the freedom of stealing that for my answer too, making my code 4 lines shorter. Thank you. – Ole V.V. Dec 09 '19 at 02:58
1

It’s not completely clear to me what result you want in general, and why. If I may assume that you want the next date that is an nth some-day-of-week of some month, it’s a little more complicated than your code. EDIT: NorthernSky is correct in the comment under his/her answer that .with(TemporalAdjusters.dayOfWeekInMonth(1, DayOfWeek.MONDAY)) more directly and briefly gets us what we need. This should work:

    ZoneId zone = ZoneId.of("Africa/Bamako");
    LocalDate today = LocalDate.now(zone);
    LocalDate nextBookingDate = today.with(Month.JANUARY)
            .with(TemporalAdjusters.dayOfWeekInMonth(1, DayOfWeek.MONDAY));
    if (nextBookingDate.isBefore(today)) {
        // Take next year instead
        nextBookingDate = today.plusYears(1)
                .with(Month.JANUARY)
                .with(TemporalAdjusters.dayOfWeekInMonth(1, DayOfWeek.MONDAY));
    }

    System.out.println("Next booking date: " + nextBookingDate);

Output when I ran the code just now, was:

Next booking date: 2020-01-06

TemporalAdjusters.dayOfWeekInMonth() will get us the 1st Monday, 3rd Tuesday, etc., of the month. So feed any day of week and any number up to 4 or 5 into this method.

Please supply your desired time zone where I put Africa/Bamako since it is never the same date in all time zones.

Link: Documentation of TemporalAdjusters.dayOfWeekInMonth().

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161