Skip to content

Conversation

UInt2048
Copy link

@UInt2048 UInt2048 commented Oct 5, 2025

The definitions of these macros do not match their documentation.

  • MIN_CALENDAR_TIME does indeed represent Julian day 0 (proleptic Gregorian -4713-11-24 12:00:00 +0000 = November 24, 4714 BC), but it is documented incorrectly as -4713-01-01 12:00:00 +0000 which is 4714 BC instead of the correct year -4712 = 4713 BC
  • MAX_CALENDAR_TIME does not represent 50000-01-01 00:00:00 +0000 but in fact 506713-02-07 00:00:00 +0000

This pull request proposes to keep the existing behavior but properly document it

Copy link
Contributor

@parkera parkera left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like we already made this fix in swift-foundation's Date.swift.

@parkera
Copy link
Contributor

parkera commented Oct 6, 2025

@swift-ci test

@UInt2048
Copy link
Author

UInt2048 commented Oct 6, 2025

@parkera Sorry, I had to push a correction to the PR after checking the definition of Julian day 0. It appears both swift-foundation's Date.swift and this file both incorrectly use Julian year -4713 (4714 BC) instead of -4712 (4713 BC) as the date of Julian day 0 in the comment, despite the interval itself appearing to be correct.

https://github.com/swiftlang/swift-foundation/blob/abfcc288dfca47d47396d099ba8b5269d17f4b06/Sources/FoundationEssentials/Date.swift#L392

@parkera parkera requested a review from itingliu October 6, 2025 18:07
@UInt2048
Copy link
Author

UInt2048 commented Oct 6, 2025

Out of curiosity, where does the date 506713-02-07 00:00:00 +0000 come from? It seems like the ICU universal time scale only has a range back to 29,000 BC and up to 29,000 AD, so the only thing I can think of is that 25,000 years or so were added to the back half of the range since dates before Julian day 0 weren't supported and that number (probably 53,286 AD or so) was rounded down to get 50,000 AD like the current documentation says, but then that maximum was miscomputed.

On the other hand, things like the iOS Calendar app seem to work fine with the full range up to 506713 AD (as far as I can tell with the Gregorian calendar anyways) so it doesn't seem to be posing issues in practice if this theory is actually what happened.

@itingliu
Copy link
Contributor

Out of curiosity, where does the date 506713-02-07 00:00:00 +0000 come from? It seems like the ICU universal time scale only has a range back to 29,000 BC and up to 29,000 AD, so the only thing I can think of is that 25,000 years or so were added to the back half of the range since dates before Julian day 0 weren't supported and that number (probably 53,286 AD or so) was rounded down to get 50,000 AD like the current documentation says, but then that maximum was miscomputed.

ICU has this implicit limit in their implementation that would cause some of their API to become no-op when the input exceeds the limit: https://github.com/swiftlang/swift-foundation-icu/blob/122f088ccda752062b4c44d4d8471ecb3638da32/icuSources/i18n/gregocal.cpp#L71

// setTimeInMillis() limits the Julian day range to +/-7F000000.
// This would seem to limit the year range to:
//  ms=+183882168921600000  jd=7f000000  December 20, 5828963 AD
//  ms=-184303902528000000  jd=81000000  September 20, 5838270 BC
// HOWEVER, CalendarRegressionTest/Test4167060 shows that the actual
// range limit on the year field is smaller (~ +/-140000). [alan 3.0]

We decided to set a cap on our own instead of relying on their implicit limits so we know exactly what we're doing. The upper bound is just a random day in the far far future that sits safely below ICU's upper bound.

@itingliu
Copy link
Contributor

@swift-ci please test

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants