-
Notifications
You must be signed in to change notification settings - Fork 204
Double-double Date #1533
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Double-double Date #1533
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
a5e81fa
Double-double Date
stephentyrone 4f8d3f2
Add DoubleDouble.swift to CMakeLists
stephentyrone 541a205
Fix up ParseStrategy tests for Date to account for Double-Double.
stephentyrone 70a7c54
Re-enable some Regex component tests
stephentyrone 3aea22c
Add comment explaining rationale for DoubleDouble storage on Date
stephentyrone File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,38 +12,45 @@ | |
|
||
/// DateInterval represents a closed date interval in the form of [startDate, endDate]. It is possible for the start and end dates to be the same with a duration of 0. DateInterval does not support reverse intervals i.e. intervals where the duration is less than 0 and the end date occurs earlier in time than the start date. | ||
@available(macOS 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) | ||
public struct DateInterval : Comparable, Hashable, Codable, Sendable { | ||
public struct DateInterval: Comparable, Hashable, Codable, Sendable { | ||
|
||
/// The start date. | ||
public var start : Date | ||
public var start: Date | ||
|
||
/// Underlying storage for `duration` | ||
internal var _duration: DoubleDouble | ||
|
||
/// The end date. | ||
/// | ||
/// - precondition: `end >= start` | ||
public var end : Date { | ||
public var end: Date { | ||
get { | ||
return start + duration | ||
return Date(start._time + _duration) | ||
} | ||
set { | ||
precondition(newValue >= start, "Reverse intervals are not allowed") | ||
duration = newValue.timeIntervalSinceReferenceDate - start.timeIntervalSinceReferenceDate | ||
_duration = (newValue._time - start._time) | ||
} | ||
} | ||
|
||
/// The duration. | ||
/// The duration | ||
/// | ||
/// - precondition: `duration >= 0` | ||
public var duration : TimeInterval { | ||
willSet { | ||
public var duration: TimeInterval { | ||
get { | ||
_duration.head | ||
} | ||
set { | ||
precondition(newValue >= 0, "Negative durations are not allowed") | ||
_duration = DoubleDouble(uncheckedHead: newValue, tail: 0) | ||
} | ||
} | ||
|
||
/// Initializes a `DateInterval` with start and end dates set to the current date and the duration set to `0`. | ||
public init() { | ||
let d = Date() | ||
start = d | ||
duration = 0 | ||
_duration = .zero | ||
} | ||
|
||
/// Initialize a `DateInterval` with the specified start and end date. | ||
|
@@ -52,7 +59,7 @@ public struct DateInterval : Comparable, Hashable, Codable, Sendable { | |
public init(start: Date, end: Date) { | ||
precondition(end >= start, "Reverse intervals are not allowed") | ||
self.start = start | ||
duration = end.timeIntervalSince(start) | ||
_duration = end._time - start._time | ||
} | ||
|
||
/// Initialize a `DateInterval` with the specified start date and duration. | ||
|
@@ -61,7 +68,7 @@ public struct DateInterval : Comparable, Hashable, Codable, Sendable { | |
public init(start: Date, duration: TimeInterval) { | ||
precondition(duration >= 0, "Negative durations are not allowed") | ||
self.start = start | ||
self.duration = duration | ||
_duration = DoubleDouble(uncheckedHead: duration, tail: 0) | ||
} | ||
|
||
/** | ||
|
@@ -162,6 +169,24 @@ public struct DateInterval : Comparable, Hashable, Codable, Sendable { | |
public static func <(lhs: DateInterval, rhs: DateInterval) -> Bool { | ||
return lhs.compare(rhs) == .orderedAscending | ||
} | ||
|
||
enum CodingKeys: String, CodingKey { | ||
case start = "start" | ||
case duration = "duration" | ||
} | ||
|
||
public init(from decoder: Decoder) throws { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is effectively identical to the current auto-generated implementation, right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's the idea! |
||
let container = try decoder.container(keyedBy: CodingKeys.self) | ||
let start = try container.decode(Date.self, forKey: .start) | ||
let duration = try container.decode(TimeInterval.self, forKey: .duration) | ||
self.init(start: start, duration: duration) | ||
} | ||
|
||
public func encode(to encoder: Encoder) throws { | ||
var container = encoder.container(keyedBy: CodingKeys.self) | ||
try container.encode(start, forKey: .start) | ||
try container.encode(duration, forKey: .duration) | ||
} | ||
} | ||
|
||
@available(macOS 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) | ||
|
Oops, something went wrong.
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note for myself: we should/could probably add a helper method somewhere to decompose the floating point second into the whole number and the fractional part. IIRC we have quite a few places where we're doing it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll take a note to do this as part of the follow-on work.