3

I only found a solution for Joda Time.

My solution works only if the last day is not in the first week:

LocalDate.now() // or any other LocalDate
  .withDayOfMonth(31)
  .withMonth(12)
  .get(weekFields.weekOfWeekBasedYear())

So what is the correct way in Java Time (like in Joda Time)?

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
pme
  • 14,156
  • 3
  • 52
  • 95
  • So you are trying to determine whether there are 52 or 53 (numbered) weeks in the current year, have I understood correctly? For American or international week numbering, or should it work for both? – Ole V.V. May 26 '17 at 09:43
  • Since according to ISO a week belongs in the year where at least four of its days lie, you may query about the week number of December 28. Since there are only three days after this day, it is guarantted to be in the last numbered week of the year. A bit tricky, I admit. Similarly January 4 is always in week 1. – Ole V.V. May 26 '17 at 12:22
  • Note that your code will only work if run in months with 31 days! You need to swap the two lines `.withDayOfMonth(31)` and `.withMonth(12)`. – steffen May 26 '17 at 13:00

4 Answers4

12

This information is available directly using the java.time.* API.

The key method is rangeRefinedBy(Temporal) on TemporalField. It allows you to obtain a ValueRange object that provides the minimum and maximum values for the field, refined by the temporal object passed in.

To find out how many ISO weeks there are in the year, do the following:

LocalDate date = LocalDate.of(2015, 6, 1);
long weeksInYear = IsoFields.WEEK_OF_WEEK_BASED_YEAR.rangeRefinedBy(date).getMaximum();
System.out.println(weeksInYear);

Note that the date you pass in is used to determine the answer. So when passing in dates in early January or late December ensure you understand how the ISO week-based calendar works, and the difference between the calendar year and the week-based year.

JodaStephen
  • 60,927
  • 15
  • 95
  • 117
  • 1
    It just keeps amazing me that we have such a breath of functionality now with Java 8 time libraries. – YoYo Jan 10 '18 at 02:23
1

If one wants to get the week number based on 7 days no matter when the week starts and how many days the first partial week of the year has, ChronoField.ALIGNED_WEEK_OF_YEAR might be helpful.

For example, the 1st of January 2016 based on the ISO-8601 definition (where a week starts on Monday and the first week has a minimum of 4 days) falls into week number 0, but in the aligned it is week number 1.

    LocalDate date = LocalDate.of(2016, 1, 1);

    int iso8601 = date.get(WeekFields.ISO.weekOfYear()); // result is 0

    int aligned = date.get(ChronoField.ALIGNED_WEEK_OF_YEAR); // result is 1
zoomout
  • 399
  • 3
  • 6
0

It seems that when the last day is in the first week, you don't want to get 1 as an answer but 52/3/4, in which case you may be looking for:

LocalDate.of(2017, 12, 31).get(WeekFields.ISO.weekOfYear());

There are several ways to define week numbers - if that doesn't do what you want you need to clarify which method you want to use.

assylias
  • 321,522
  • 82
  • 660
  • 783
0

The correct and best solution is given by @JodaStephen. Here are some alternatives anyways.

December, 28th is always in the last week of a year, because the remaining three days after can not form a major part of another week:

int weeks = LocalDate.of(2017, 12, 28).get(WeekFields.ISO.weekOfYear());

A year has 53 weeks if it starts or ends with a thursday:

Year year = Year.of(2017);
DayOfWeek firstDay = year.atDay(1).getDayOfWeek();
DayOfWeek lastDay = year.atDay(year.length()).getDayOfWeek();
int weeks = firstDay == DayOfWeek.THURSDAY || lastDay == DayOfWeek.THURSDAY ? 53 : 52;

And finally this will give you the "week number" of the last day of year. It's 53 also in cases where the last week's number is 52 iff the major part of the last day's week lies in the next year (the week is claimed by the next year).

// This will not give the correct number of weeks for a given year
Year year = Year.of(2018);
year.atDay(year.length()).get(WeekFields.ISO.weekOfYear()); // 53

That's what you actually did.

steffen
  • 16,138
  • 4
  • 42
  • 81
  • Without having fully understood the question I tried with years 2010 through 2020. For 2015 and 2020 I get 53 weeks. For 2010, 2011, 2016 and 2017, I get 52. I believe that all of this is correct. My confusion is that with 2012, 2013, 2014, 2018 and 2019 the first snippet yields 53, the second snippet 52. – Ole V.V. May 26 '17 at 12:19
  • Thanks for satisfying my curiosity, I think I understand the difference now. – Ole V.V. May 26 '17 at 13:15