Skip to content

Commit 8010dfe

Browse files
parkeraCatfish-Man
andauthored
Date comparison handles nanoseconds incorrectly (swiftlang#289)
rdar://116433981 Co-authored-by: David Smith <[email protected]>
1 parent 62500a5 commit 8010dfe

File tree

1 file changed

+15
-15
lines changed

1 file changed

+15
-15
lines changed

Sources/FoundationEssentials/Calendar/Calendar.swift

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -721,8 +721,8 @@ public struct Calendar : Hashable, Equatable, Sendable {
721721
}
722722
case .minute:
723723
// assumes that time zone or other adjustments are always whole minutes
724-
var (int1, _) = modf(date1.timeIntervalSinceReferenceDate)
725-
var (int2, _) = modf(date2.timeIntervalSinceReferenceDate)
724+
var int1 = date1.timeIntervalSinceReferenceDate.rounded(.down)
725+
var int2 = date2.timeIntervalSinceReferenceDate.rounded(.down)
726726
int1 = floor(int1 / 60.0)
727727
int2 = floor(int2 / 60.0)
728728
if int1 == int2 {
@@ -733,8 +733,8 @@ public struct Calendar : Hashable, Equatable, Sendable {
733733
return .orderedAscending
734734
}
735735
case .second:
736-
let (int1, _) = modf(date1.timeIntervalSinceReferenceDate)
737-
let (int2, _) = modf(date2.timeIntervalSinceReferenceDate)
736+
let int1 = date1.timeIntervalSinceReferenceDate.rounded(.down)
737+
let int2 = date2.timeIntervalSinceReferenceDate.rounded(.down)
738738
if int1 == int2 {
739739
return .orderedSame
740740
} else if int2 < int1 {
@@ -743,22 +743,22 @@ public struct Calendar : Hashable, Equatable, Sendable {
743743
return .orderedAscending
744744
}
745745
case .nanosecond:
746-
let (int1, frac1) = modf(date1.timeIntervalSinceReferenceDate)
747-
let (int2, frac2) = modf(date2.timeIntervalSinceReferenceDate)
748-
if int1 == int2 {
749-
let nano1 = floor(frac1 * 1000000000.0)
750-
let nano2 = floor(frac2 * 1000000000.0)
746+
func split(_ timeInterval: Double) -> (secs: Double, nano: Double) {
747+
let secs = timeInterval.rounded(.towardZero)
748+
let nano = (1e9 * (timeInterval - secs)).rounded(.towardZero)
749+
return (secs, nano)
750+
}
751+
752+
let (secs1, nano1) = split(date1.timeIntervalSinceReferenceDate)
753+
let (secs2, nano2) = split(date2.timeIntervalSinceReferenceDate)
754+
if secs1 == secs2 {
751755
if nano1 == nano2 {
752756
return .orderedSame
753757
} else if nano1 < nano2 {
754-
return .orderedDescending
758+
return .orderedAscending
755759
} else {
756-
return .orderedSame
760+
return .orderedDescending
757761
}
758-
} else if int2 < int1 {
759-
return .orderedDescending
760-
} else {
761-
return .orderedAscending
762762
}
763763
default:
764764
break

0 commit comments

Comments
 (0)