Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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, accuracy 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.