Reputation: 1462
I'm sure I'm just missing something here, but it continues to elude me.
Why does SUNDAY_START produce a week number of 1 for 2020-12-29 instead of 53?
Is it because I'm misinterpreting what the Oracle docs say? Or am I missing something further?
Details
Going to https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/temporal/WeekFields.html#SUNDAY_START shows that SUNDAY_START appears to follow the same rules as above. If I use the following code...
ZonedDateTime zdt = ZonedDateTime.ofInstant(/* representation of Dec. 29, 2020 */, ZoneId.of("UTC"));
TemporalField wn = WeekFields.SUNDAY_START.weekOfWeekBasedYear();
int weekNumber = zdt.get(wn);
Then "weekNumber" is 1, when I would expect it to be 53.
If I use WeekFields.ISO
instead, I get 53; however, the definition of ISO is that it uses Monday as the start of the week, which isn't true in the case I'm dealing with and I'm unsure of future ramifications of just using ISO instead of SUNDAY_START.
What am I missing?
The Answer
Based on the comments below (thank you to Basil and Andreas), I was indeed misreading the Oracle documentation, which states:
Defined as starting on Sunday and with a minimum of 1 day in the month.
The "minimum of 1 day in the month" was the part that threw me for a loop within the context of a new year.
With the clarifications below, it's clear that since Jan. 1, 2021 occurs on a Friday, and the SUNDAY_START week starts on a Sunday, that this week would, in fact, be week number 1 in this case.
Motivation
I had originally asked this question as part of an attempt to better understand SUNDAY_START. The motivation for this was to find a way to recreate MySQL's WEEK() "mode 6" (that is, a Sunday start to the week with week 1 being the first week with 4 or more days this year).
I had forgotten about the ability to create custom week fields with a specified start day and the minimum number of days in the month for it to contain.
Still, I am grateful to have cleared up my misunderstanding of the Javadocs for SUNDAY_START, and I hope this post might be useful to someone in the future.
Thank you for everyone's comments and answers and I apologize for any initial confusion.
Upvotes: 2
Views: 1169
Reputation: 159106
https://savvytime.com/week-number is wrong.
When you show Country: United States
, Year: 2020
, it shows:
Week 53 December 27, 2020 January 2, 2021 Current Week
When you show Country: United States
, Year: 2021
, it shows:
Week 1 December 27, 2020 January 2, 2021 Current Week
How can the same date range be both week 53 and week 1? It can't. The site is broken.
UPDATE: From comment:
needing a Java datetime "equivalent" of MySQL's
WEEK()
function using mode 6
That's easy enough. Mode 6 is defined as:
So you get a WeekFields
for that:
WeekFields weekMode6 = WeekFields.of(/*firstDayOfWeek=*/DayOfWeek.SUNDAY,
/*minimalDaysInFirstWeek=*/4);
For reference, the two predefined WeekFields
instances are defined as:
ISO = new WeekFields(DayOfWeek.MONDAY, 4);
SUNDAY_START = WeekFields.of(DayOfWeek.SUNDAY, 1);
Upvotes: 5
Reputation: 338730
Your linked web site uses undisclosed rules for defining a week:
Weeks are according United States calendar rules, Sunday first day and weeks are Sunday to Saturday
The phrase “United States calendar rules” has no meaning. There are many sets of calendar rules in the US: Various accounting organizations make rules, IRS has rules, industries have their own rules such as a two-season year in some retail, and private companies define their own rules, sometimes quite innovative.
And the rest of that definition is unclear.
Furthermore, that site seems to be inexplicably self-contradictory, as seen in the Answer by Andreas.
I would not consider that web site to be authoritative.
In contrast, the ISO 8601 calendar is very clearly defined, including the definition of a week and week-based-year:
This definition means that a week-based year may contain a few days from the previous calendar year in week # 1, and may contain a few days from the following calendar-year in the last week of the week-based year.
Am not sure exactly what your goal is, as your Question is unclear. But if the ISO 8601 rules match those of your business, then use the implementation in java.time.
YearWeek
Even better, add the ThreeTen-Extra library to your project. This library is led by the same man who led the java.time JSR 310 project, Stephen Colebourne. This library brings additional functionality to java.time. In particular, see the YearWeek
class for ISO 8601 weeks.
Upvotes: 4