Swift 3-сравнение объектов даты


Я обновляю свое приложение до синтаксиса Swift 3.0 (я знаю, что он все еще находится в бета-версии, но я хочу быть готовым, как только он будет выпущен).

до предыдущей бета-версии Xcode (Beta 5) я смог сравнить два Date объекты, использующие операнды <,> и ==. Но в последней бета-версии (Beta 6) это больше не работает. Вот несколько скриншотов:

как вы можете видеть на обоих скриншотах, это два Date объекты. Но я получаю следующую ошибку:

что я делаю не так? Функции по-прежнему объявлены в Date класс:

static func >(Date, Date)

возвращает true, если левая дата позже по времени, чем правая дата.

это просто бета-ошибка или я делаю что-то не так?

10 57

10 ответов:

Я пробовал этот фрагмент в Xcode 8 beta 6, и он работает нормально.

let date1 = Date()
let date2 = Date().addingTimeInterval(100)

if date1 == date2
{
}
else if date1 > date2
{
}
else if date1 < date2
{
}

Date и Comparable & Equatable (по состоянию на Swift 3)

этот ответ дополняет ответ @ Ankit Thakur.

начиная с Swift 3 The Date структура (на основе NSDate класс) принимает Comparable и Equatable протоколов.

  • Comparable требует Date выполнить операторы: <,<=,>,>=.
  • Equatable требует Date выполнить == оператора.
  • Equatable позволяет Date использовать реализацию по умолчанию != оператор (который является инверсией Equatable== реализация оператора).

следующий пример кода выполняет эти операторы сравнения и подтверждает, какие сравнения верны с print заявления.

функция сравнения

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: ",  ")
}

Пример Использования

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

in Swift 3, Дата сопоставима Так что мы можем напрямую сравнить даты, как

let date1 = Date()
let date2 = Date()

let isGreater = date1 > date2
print(isGreater)

let isSmaller = date1 < date2
print(isSmaller)

let isEqual = date1 == date2
print(isEqual)

посмотреть этот http://iswift.org/cookbook/compare-2-dates

Вам Даты:

// Get current date
let dateA = NSDate()

// Get a later date (after a couple of milliseconds)
let dateB = NSDate()

использование оператора SWITCH

// Compare them
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")
}

использование оператора IF

 if datePickerTo.date.compare(datePicker.date) == .orderedAscending {
     datePickerTo.date = datePicker.date
 }

для меня проблема заключалась в том, что у меня было собственное расширение для класса Date, которое определяло все операторы сравнения. Теперь (поскольку swift 3) эта дата сопоставима, эти расширения не нужны. Поэтому я прокомментировал их, и это сработало.

SWIFT 3: Не знаю, если это то, что вы ищете. Но я сравниваю строку с текущей меткой времени, чтобы увидеть, если моя строка старше, что сейчас.

func checkTimeStamp(date: String!) -> Bool {
        let dateFormatter: DateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
        dateFormatter.locale = Locale(identifier:"en_US_POSIX")
        let datecomponents = dateFormatter.date(from: date)

        let now = Date()

        if (datecomponents! >= now) {
            return true
        } else {
            return false
        }
    }

использовать:

if (checkTimeStamp(date:"2016-11-21 12:00:00") == false) {
    // Do something
}

сравнивать дату только с годом-месяцем-днем и без времени для меня работало так:

     let order = Calendar.current.compare(self.startDate, to: compareDate!, toGranularity: .day)  

                      switch order {
                        case .orderedAscending:
                            print("\(gpsDate) is after \(self.startDate)")
                        case .orderedDescending:
                            print("\(gpsDate) is before \(self.startDate)")
                        default:
                            print("\(gpsDate) is the same as \(self.startDate)")
                        }

на момент написания этой статьи Swift изначально поддерживает сравнение дат со всеми операторами сравнения (т. е. <,<=,==,>= и >). Вы также можете сравнить дополнительные даты, но ограничены <,== и >. Если вам нужно сравнить две необязательные даты с помощью <= или >=, т. е.

let date1: Date? = ...
let date2: Date? = ...
if date1 >= date2 { ... }

вы можете перегрузить <= и >=операторы для поддержки optionals:

func <= <T: Comparable>(lhs: T?, rhs: T?) -> Bool {
    return lhs == rhs || lhs < rhs
}

func >= <T: Comparable>(lhs: T?, rhs: T?) -> Bool {
    return lhs == rhs || lhs > rhs
}
extension Date {
 func isBetween(_ date1: Date, and date2: Date) -> Bool {
    return (min(date1, date2) ... max(date1, date2)).contains(self)
  }
}

let resultArray = dateArray.filter { .dateObj!.isBetween(startDate, and: endDate) }

другой способ сделать это:

    switch date1.compare(date2) {
        case .orderedAscending:
            break

        case .orderedDescending:
            break;

        case .orderedSame:
            break
    }