简体   繁体   中英

Java Time: Get max number of weeks for particular year

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)?

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.

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

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM