Java 时间:获取特定年份的最大周数

Java Time: Get max number of weeks for particular year

我只找到了 Joda Time 的解决方案。

只有当最后一天不在第一周时,我的解决方案才有效:

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

那么 Java Time 中的正确方法是什么(就像在 Joda Time 中一样)?

似乎当最后一天在第一周时,您不想得到 1 作为答案而是 52/3/4,在这种情况下您可能正在寻找:

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

有多种方法可以定义周数 - 如果这不能满足您的要求,您需要说明要使用哪种方法。

给出了正确的最佳解决方案。这里有一些替代方案。

12月28日总是在一年的最后一周,因为之后剩下的三天不能构成另一周的主要部分:

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

一年有 53 周,如果它以星期四开始或结束:

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;

最后,这将为您提供一年中最后一天的 "week number"。它也是 53 在最后一周的数字是 52 的情况下当且仅当最后一天的一周的主要部分位于下一年(下一年声称该周)。

// 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

这就是你实际所做的。

此信息可直接使用 java.time.* API。

关键方法是rangeRefinedBy(Temporal) TemporalField。它允许您获得一个 ValueRange 对象,该对象提供字段的最小值和最大值,由传入的时间对象细化。

要了解一年中有多少个 ISO 周,请执行以下操作:

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

请注意,您输入的日期用于确定答案。因此,在 1 月初或 12 月底传递日期时,请确保您了解 ISO 基于周的日历的工作原理,以及日历年和基于周的年份之间的区别。

如果无论一周从何时开始以及一年中的第一个部分周有多少天,如果想要根据 7 天获取周数,ChronoField.ALIGNED_WEEK_OF_YEAR 可能会有所帮助。

例如,根据 ISO-8601 定义(一周从星期一开始,第一周至少有 4 天)的 2016 年 1 月 1 日属于第 0 周,但在对齐中它是第 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