如何在 Java 8 中遍历一年中的每个星期?
How can I iterate over every week in a year in Java 8?
如果我在这里混淆了任何与 ISO 日期相关的术语,请提前致歉。
我希望能够在给定年份(比如 2015 年)的每个星期进行迭代。我意识到您可以计算 1/1/2015 和 12/31/2015 之间的周数,但这不符合一周的 ISO 标准。相反,它给出了两个日期之间 7 天的天数。一年中的第一个 ISO 周不一定从 1/1/2015 开始。
如果我能得到第一周的第一个日期,我相信我可以简单地通过 ZonedDateTime.plusWeeks(1)
迭代 52 周。您可以通过字段访问器获取任意日期的周数:
ZonedDateTime date = ZonedDateTime.now();
WeekFields weekFields = WeekFields.of(Locale.getDefault());
int weekNumber = date.get(weekFields.weekOfWeekBasedYear());
鉴于此,我认为一定可以在Java8时间[=]中获取特定年的第一周的第一天26=],但我还没有找到办法。
您可以构造一个日期并将其调整为一年中第一周的第一天,方法如下:
int year = 2016;
WeekFields weekFields = WeekFields.ISO;
LocalDate date = LocalDate.now().with(weekFields.weekBasedYear(), year)
.with(weekFields.weekOfWeekBasedYear(), 1)
.with(ChronoField.DAY_OF_WEEK, 1);
感谢 JodaStephen's comment, another way to put it would be to use the IsoFields
class。
LocalDate date = LocalDate.now().with(IsoFields.WEEK_BASED_YEAR, year)
.with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, 1)
.with(ChronoField.DAY_OF_WEEK, 1);
WeekFields.ISO
表示周的ISO定义:
The ISO-8601 definition, where a week starts on Monday and the first week has a minimum of 4 days.
The ISO-8601 standard defines a calendar system based on weeks. It uses the week-based-year and week-of-week-based-year concepts to split up the passage of days instead of the standard year/month/day.
Note that the first week may start in the previous calendar year. Note also that the first few days of a calendar year may be in the week-based-year corresponding to the previous calendar year.
根据该定义,您可以得到:
weekBasedYear()
代表week-based-year字段:
This represents the concept of the year where weeks start on a fixed day-of-week, such as Monday and each week belongs to exactly one year.
在这种情况下,我们要将其设置为想要的年份。
weekOfWeekBasedYear()
表示week-based-year
中的星期
This represents the concept of the count of weeks within the year where weeks start on a fixed day-of-week, such as Monday and each week belongs to exactly one year.
在这种情况下,我们需要基于周的年份的第一周,因此我们将其设置为 1。
ChronoField.DAY_OF_WEEK
表示星期几。在这种情况下,我们想要一周的第一天,所以我们设置为 1。
然后,有了这样一个日期,您确实可以通过调用 LocalDate.plusWeeks(1)
遍历一年中的所有星期。问题是:你需要迭代多少次?一年可能超过 52 周。以周为基础的一年有 52 周或 53 周。
您可以使用以下方法检索周数。此调用 rangeRefinedBy(date)
检索给定日期的一年中的星期字段的有效值,并获取其最大值。
long maxWeekOfYear = weekFields.weekOfWeekBasedYear().rangeRefinedBy(date).getMaximum();
如果我在这里混淆了任何与 ISO 日期相关的术语,请提前致歉。
我希望能够在给定年份(比如 2015 年)的每个星期进行迭代。我意识到您可以计算 1/1/2015 和 12/31/2015 之间的周数,但这不符合一周的 ISO 标准。相反,它给出了两个日期之间 7 天的天数。一年中的第一个 ISO 周不一定从 1/1/2015 开始。
如果我能得到第一周的第一个日期,我相信我可以简单地通过 ZonedDateTime.plusWeeks(1)
迭代 52 周。您可以通过字段访问器获取任意日期的周数:
ZonedDateTime date = ZonedDateTime.now();
WeekFields weekFields = WeekFields.of(Locale.getDefault());
int weekNumber = date.get(weekFields.weekOfWeekBasedYear());
鉴于此,我认为一定可以在Java8时间[=]中获取特定年的第一周的第一天26=],但我还没有找到办法。
您可以构造一个日期并将其调整为一年中第一周的第一天,方法如下:
int year = 2016;
WeekFields weekFields = WeekFields.ISO;
LocalDate date = LocalDate.now().with(weekFields.weekBasedYear(), year)
.with(weekFields.weekOfWeekBasedYear(), 1)
.with(ChronoField.DAY_OF_WEEK, 1);
感谢 JodaStephen's comment, another way to put it would be to use the IsoFields
class。
LocalDate date = LocalDate.now().with(IsoFields.WEEK_BASED_YEAR, year)
.with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, 1)
.with(ChronoField.DAY_OF_WEEK, 1);
WeekFields.ISO
表示周的ISO定义:
The ISO-8601 definition, where a week starts on Monday and the first week has a minimum of 4 days.
The ISO-8601 standard defines a calendar system based on weeks. It uses the week-based-year and week-of-week-based-year concepts to split up the passage of days instead of the standard year/month/day.
Note that the first week may start in the previous calendar year. Note also that the first few days of a calendar year may be in the week-based-year corresponding to the previous calendar year.
根据该定义,您可以得到:
weekBasedYear()
代表week-based-year字段:This represents the concept of the year where weeks start on a fixed day-of-week, such as Monday and each week belongs to exactly one year.
在这种情况下,我们要将其设置为想要的年份。
中的星期weekOfWeekBasedYear()
表示week-based-yearThis represents the concept of the count of weeks within the year where weeks start on a fixed day-of-week, such as Monday and each week belongs to exactly one year.
在这种情况下,我们需要基于周的年份的第一周,因此我们将其设置为 1。
ChronoField.DAY_OF_WEEK
表示星期几。在这种情况下,我们想要一周的第一天,所以我们设置为 1。
然后,有了这样一个日期,您确实可以通过调用 LocalDate.plusWeeks(1)
遍历一年中的所有星期。问题是:你需要迭代多少次?一年可能超过 52 周。以周为基础的一年有 52 周或 53 周。
您可以使用以下方法检索周数。此调用 rangeRefinedBy(date)
检索给定日期的一年中的星期字段的有效值,并获取其最大值。
long maxWeekOfYear = weekFields.weekOfWeekBasedYear().rangeRefinedBy(date).getMaximum();