Swift 3 - Comparing Date objects
I'm updating my app to Swift 3.0 syntax (I know it's still in beta but I want to be prepared as soon as it released).
Until the previous Beta of Xcode (Beta 5) I was able to compare two Date
objects using the operands <
, >
and ==
. But in the latest beta (Beta 6) this isn't working any more. Here are some screenshots:
As you can see in both screenshots, these are two Date
objects. But I get the following error:
What am I doing wrong? The functions are still declared in the Date
class:
static func >(Date, Date)
Returns true if the left hand Date is later in time than the right hand Date.
Is this just a Beta bug or am I doing something wrong?
Solution 1:
I have tried this snippet (in Xcode 8 Beta 6), and it is working fine.
let date1 = Date()
let date2 = Date().addingTimeInterval(100)
if date1 == date2 { ... }
else if date1 > date2 { ... }
else if date1 < date2 { ... }
Solution 2:
Date
is Comparable
& Equatable
(as of Swift 3)
This answer complements @Ankit Thakur's answer.
Since Swift 3 the Date
struct (based on the underlying NSDate
class) adopts the Comparable
and Equatable
protocols.
-
Comparable
requires thatDate
implement the operators:<
,<=
,>
,>=
. -
Equatable
requires thatDate
implement the==
operator. -
Equatable
allowsDate
to use the default implementation of the!=
operator (which is the inverse of theEquatable
==
operator implementation).
The following sample code exercises these comparison operators and confirms which comparisons are true with print
statements.
Comparison function
import Foundation
func describeComparison(date1: Date, date2: Date) -> String {
var descriptionArray: [String] = []
if date1 < date2 {
descriptionArray.append("date1 < date2")
}
if date1 <= date2 {
descriptionArray.append("date1 <= date2")
}
if date1 > date2 {
descriptionArray.append("date1 > date2")
}
if date1 >= date2 {
descriptionArray.append("date1 >= date2")
}
if date1 == date2 {
descriptionArray.append("date1 == date2")
}
if date1 != date2 {
descriptionArray.append("date1 != date2")
}
return descriptionArray.joined(separator: ", ")
}
Sample Use
let now = Date()
describeComparison(date1: now, date2: now.addingTimeInterval(1))
// date1 < date2, date1 <= date2, date1 != date2
describeComparison(date1: now, date2: now.addingTimeInterval(-1))
// date1 > date2, date1 >= date2, date1 != date2
describeComparison(date1: now, date2: now)
// date1 <= date2, date1 >= date2, date1 == date2
Solution 3:
from Swift 3 and above, Date is Comparable so we can directly compare dates like
let date1 = Date()
let date2 = Date().addingTimeInterval(50)
let isGreater = date1 > date2
print(isGreater)
let isSmaller = date1 < date2
print(isSmaller)
let isEqual = date1 == date2
print(isEqual)
Alternatively We can create extension on Date
extension Date {
func isEqualTo(_ date: Date) -> Bool {
return self == date
}
func isGreaterThan(_ date: Date) -> Bool {
return self > date
}
func isSmallerThan(_ date: Date) -> Bool {
return self < date
}
}
Use: let isEqual = date1.isEqualTo(date2)
Solution 4:
Don't use comparators <
, >
, ==
, !=
.
Use compare(_ other: Date)
function.
Usage
// Get current date
let dateA = Date()
// Get a later date (after a couple of milliseconds)
let dateB = Date()
// Compare them using switch
switch dateA.compare(dateB) {
case .orderedAscending : print("Date A is earlier than date B")
case .orderedDescending : print("Date A is later than date B")
case .orderedSame : print("The two dates are the same")
}
// Compare them using if
if dateA.compare(dateB) == .orderedAscending {
datePickerTo.date = datePicker.date
}