Skip to content

Conversation

github-actions[bot]
Copy link
Contributor

This PR was automatically opened by a GitHub action. Review the changes included in this PR and determine if they should be included in the release branch. If yes, merge the PR. Otherwise revert changes that should not be included on this branch.

Adapts Date to use a double-Double representation (the underlying representation is the sum of two double-precision values, giving about 106 bits of precision).

Previously Date was backed by a single Double measuring time since Jan 1 2001 in seconds. Because Double's precision is non-uniform, this means that times within a hundred days of the epoch are represented with approximately nanosecond precision, but as you get farther away from that date the precision decreases. For times close to today, it has been reduced to about 100ns.

The obvious thing would be to adopt an integer-based representation similar to C's timespec (32b nanoseconds, 64b seconds) or Swift's Duration (128b attoseconds). These representations suffer from a few difficulties:

- Existing API on Date takes and produces TimeInterval (aka Double). Making Date use an integer representation internally would mean that existing users of the public API would suddently start getting different results for computations that were previously exact; even though we could add new API, and the overall system would be more precise, this would be a surprisingly subtle change for users to navigate.

- We have been told that some software interprets the raw bytes of Date as a Double for the purposes of fast serialization. These packages formally violate Foundation's API boundaries, but that doesn't help users of those packages who would abruptly be broken by switching to an integer representation.

Using DoubleDouble instead navigates these problems fairly elegantly.

- Because DoubleDouble is still a floating-point type, it still suffers from non-uniform precision. However, because DoubleDouble is so fantastically precise, it can represent dates out to ±2.5 quadrillion years at ~nanosecond or better precision, so in practice this won't be much of an issue.

- Existing API on Date will produce exactly the same result as it did previously in cases where those results were exact, minimizing surprises. In cases where the existing API was not exact, it will produce much more accurate results, even if users do not adopt new API, because its internal calculations are now more precise.

- Software that (incorrectly) interprets the raw bytes of Date as a Double will get at least as accurate of a value as it did previously (and often a more accurate value).

DateInterval gets the same treatment, so that it can benefit from more accurate internal computations as well. Follow-on work may adapt/add-to Date's API to make it easier to specify Dates with high precision.
@jmschonfeld jmschonfeld reopened this Oct 12, 2025
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.

2 participants