Calendar.nextDate mis-computes weekOfYear in certain configurations

Originator:lhunath
Number:rdar://FB12073340 Date Originated:
Status: Resolved:
Product:Foundation Product Version:
Classification:Incorrect/Unexpected Behavior Reproducible:
 
Consider the following example:

```
var calendar = Calendar(identifier: .gregorian)
calendar.timeZone = .utc
calendar.firstWeekday = 2

let date = calendar.date(from: .init(year: 2022)).flatMap {
    calendar.nextDate(after: $0, matching: DateComponents(year: 2023, weekOfYear: 3), matchingPolicy: .strict)
}!
```

This yields an incorrect value for `date`:
```
date.ISO8601Format() // INCORRECT: “2023-01-09T00:00:00Z”, SHOULD BE: “2023-01-02T00:00:00Z”
```

We can illustrate this even further by showing the date components for the date that was calculated:
```
calendar.dateComponents(Set([.year, .weekOfYear]), from: date) // INCORRECT: “year: 2023 weekOfYear: 3”, SHOULD BE: “year: 2023 weekOfYear: 2”
```

Even though we asked for a strict date result that has the components year: 2023, weekOfYear: 2, we in fact received a result with a weekOfYear component set to 3.

Unfortunately, this issue carries over into the rest of the year. If we ask for year: 2023, weekOfYear: 5, we receive a date with components year: 2023, weekOfYear: 6.

As a result, every application which relies on this API to calculate the time span of a specific week in this year will be receiving the wrong (subsequent) year under this calendar configuration.

Comments

This issue extends to other API as well:

var date = calendar.date(from: DateComponents(year: 2023))!
date = calendar.date(bySetting: .weekOfYear, value: 5, of: date)!
calendar.component(.weekOfYear, from: date) // expected “5”, yields “6”

Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!