How can i change year with LocalDate by adding weeks?

497 views Asked by At

Here is my code. This method works only for 1 ( current year). When week number is more than 53, dates start from dates in first week in current year but not the next. Year has 52 or 53 weeks, so when week is last (52or53) i have 2020-12-28 - 2021-01-03, but when I want get first week of next year (2021-01-04 - 2021-01-10) it outputs me first week from 2020 ( 2019-12-30 - 2020-01-05).


public void showPreviousNextWeekDays(DataBaseHelper dataBaseHelper, long weekChange) {
        if (weekChange >= 0) {
            LocalDate ld = LocalDate.now().plusWeeks(weekChange);

            final long weekNumber = ld.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR); //takes week from current date 



             LocalDate firstDayOfWeek = ld.ofYearDay(ld.getYear(), (int)weekNumber)
                     .with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, weekNumber)
                     .with(DayOfWeek.MONDAY);


            LocalDate lastDayOfWeek = ld.ofYearDay(ld.getYear(), (int)weekNumber)
                    .with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, weekNumber)
                    .with(DayOfWeek.SUNDAY);


            String firstAndLastDayOfWeek = firstDayOfWeek.toString() + " - " + lastDayOfWeek.toString();
            daysArrayAdapter = new ArrayAdapter<DayModel>(getActivity(), android.R.layout.simple_list_item_1, db.NextWeek(weekChange));
            daysList.setAdapter(daysArrayAdapter);

How can i go forward with years also by adding weeks?

1

There are 1 answers

1
Anonymous On BEST ANSWER

You are correct that your code is not correct. When I set weekChange to 14 and run today (September 29), I get 2019-12-30 - 2020-01-05 where expected result would be 2021-01-04 - 2020-01-10. Also for 15 and 16 weeks your code goes back to a week in the beginning of this year rather than finding a week in the beginning of next year as it should.

I suggest the following, which is also a bit simpler:

    int weekChange = 14;

    LocalDate ld = LocalDate.now(ZoneId.systemDefault()).plusWeeks(weekChange);
    LocalDate firstDayOfWeek = ld.with(DayOfWeek.MONDAY);
    LocalDate lastDayOfWeek = ld.with(DayOfWeek.SUNDAY);

    String firstAndLastDayOfWeek = firstDayOfWeek.toString() + " - " + lastDayOfWeek.toString();

    System.out.println(firstAndLastDayOfWeek);

Output when run today:

2021-01-04 - 2021-01-10

LocalDate uses the ISO calendar system including ISO weeks if not explicitly instructed otherwise. So we can be sure that ld.with(DayOfWeek.MONDAY) gives us Monday at the start of the same ISO week. Similarly ld.with(DayOfWeek.SUNDAY) gives us Sunday at the end of the ISO week. So there is nothing more to it.

What happened in your code?

Sticking to the case of weekChange 14 and running today.

ld becomes 2021-01-05 (Tuesday 14 weeks from now). This date is in week 1 of 2021, so weekNumber will be 1.

ofYearDay is a static method of LocalDate. So ld.ofYearDay(ld.getYear(), (int)weekNumber) gives you the same date as you would have got from LocalDate.ofYearDay(ld.getYear(), (int)weekNumber). It does not use ld for anything. Since weekNumber is 1, you get day 1 of 2021, so 2021-01-01. Passing the week number as the day of year to ofYearDay() is meaningless. 2021-01-01 happens to fall in week 53 of 2020. So with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, weekNumber) adjusts the date back to week 1 of 2020. This is where we go a year wrong. The result is 2020-01-03. The Monday of that week is 2019-12-30, which explains why you got this as the first day of week in the output.

The last day of week is similar. And week numbers 2 and 3 are similar since you use the week number as a day of year, and January 2 and 3 fall in the last week of the previous year, 2020, too.

How did I find out? I ran your code in my debugger. There it was clear to see. If you haven’t yet learned to use a debugger. I suggest that now is the best of all times.