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:

enter image description here enter image description here

As you can see in both screenshots, these are two Date objects. But I get the following error: enter image description here

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 that Date implement the operators: <, <=, >, >=.
  • Equatable requires that Date implement the == operator.
  • Equatable allows Date to use the default implementation of the != operator (which is the inverse of the Equatable == 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
}