web-dev-qa-db-fra.com

Swift 3 - Comparaison d'objets Date

Je mets à jour mon application avec la syntaxe Swift 3.0 (je sais qu'elle est toujours en version bêta, mais je veux être prêt dès sa publication).

Jusqu'à la version bêta précédente de Xcode (version 5), je pouvais comparer deux objets Date à l'aide des opérandes <, > et ==. Mais dans la dernière version bêta (bêta 6), cela ne fonctionne plus. Voici quelques captures d'écran:

 enter image description here  enter image description here

Comme vous pouvez le constater dans les deux captures d'écran, il s'agit de deux objets Date. Mais j'obtiens l'erreur suivante:  enter image description here

Qu'est-ce que je fais mal? Les fonctions sont toujours déclarées dans la classe Date:

static func >(Date, Date)

Renvoie true si la date de la main gauche est postérieure à la date de la main droite.

Est-ce juste un bug de la bêta ou est-ce que je fais quelque chose de mal?

67
beeef

J'ai essayé cet extrait (dans XCode 8 Beta 6), et cela fonctionne bien.

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

if date1 == date2 { ... }
else if date1 > date2 { ... }
else if date1 < date2 { ... }
128
Ankit Thakur

Date est Comparable & Equatable (à partir de Swift 3)

Cette réponse complète la réponse de @Ankit Thakur.

Depuis Swift 3, la structure Date (basée sur la classe NSDate sous-jacente) adopte les protocoles Comparable et Equatable .

  • Comparable nécessite que Date implémente les opérateurs: <, <=, >, >=.
  • Equatable nécessite que Date implémente l'opérateur ==.
  • Equatable autorise Date à utiliser l'implémentation par défaut de l'opérateur != (qui est l'inverse de l'implémentation de l'opérateur Equatable==).

L'exemple de code suivant exerce ces opérateurs de comparaison et confirme les comparaisons vraies avec les instructions print.

Fonction de comparaison

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

Exemple d'utilisation

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
42
Mobile Dan

à partir de Swift 3 et plus, la date est comparable afin que nous puissions comparer directement les dates comme

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

let isGreater = date1 > date2
print(isGreater)

let isSmaller = date1 < date2
print(isSmaller)

let isEqual = date1 == date2
print(isEqual)

Alternativement, nous pouvons créer une extension le 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
  }
}

Utilisation: let isEqual = date1.isEqualTo(date2)

24
Suhit Patil

Regardez ceci http://iswift.org/cookbook/compare-2-dates

Obtenir des dates: 

// Get current date
let dateA = NSDate()

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

Utilisation de l'instruction 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")
}

en utilisant l'instruction IF

 if datePickerTo.date.compare(datePicker.date) == .orderedAscending {
     datePickerTo.date = datePicker.date
 }
12
Luis Abreu Acevedo

Pour moi, le problème était que j'avais ma propre extension à la classe Date qui définissait tous les opérateurs de comparaison. Maintenant (depuis Swift 3) que Date est comparable, ces extensions ne sont pas nécessaires. Alors je les ai commentés et ça a fonctionné.

9
Jitendra Kulkarni

Swift 3: Je ne sais pas si c'est ce que vous cherchez. Mais je compare une chaîne à un horodatage actuel pour voir si ma chaîne est plus ancienne que maintenant.

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
        }
    }

Pour l'utiliser: 

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

Pour comparer la date seulement avec année - mois - jour et sans heure pour moi a travaillé comme ceci:

     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)")
                        }
4

Swift 5:

1) Si vous utilisez le type de date:

let firstDate  = Date()
let secondDate = Date()

print(firstDate > secondDate)  
print(firstDate < secondDate)
print(firstDate == secondDate)

2) Si vous utilisez un type de chaîne:

let firstStringDate  = "2019-05-22T09:56:00.1111111"
let secondStringDate = "2019-05-22T09:56:00.2222222"

print(firstStringDate > secondStringDate)  // false
print(firstStringDate < secondStringDate)  // true
print(firstStringDate == secondStringDate) // false 

Je ne suis pas sûr ou la deuxième option fonctionne à 100%. Mais combien je ne changerais pas les valeurs de firstStringDate et secondStringDate le résultat était correct.

1
maxwell
extension Date {
 func isBetween(_ date1: Date, and date2: Date) -> Bool {
    return (min(date1, date2) ... max(date1, date2)).contains(self)
  }
}

let resultArray = dateArray.filter { $0.dateObj!.isBetween(startDate, and: endDate) }
1
Arjun Patel

Au moment de la rédaction de ce document, Swift prend en charge, de manière native, la comparaison de dates avec tous les opérateurs de comparaison (<, <=, ==, >= et >). Vous pouvez également comparer des dates facultatives, mais elles sont limitées à <, == et >. Si vous devez comparer deux dates facultatives à l'aide de <= ou >=, c'est-à-dire.

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

Vous pouvez surcharger les opérateurs <= et >= pour prendre en charge les options:

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
}
1
NSExceptional

Une autre façon de le faire:

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

        case .orderedDescending:
            break;

        case .orderedSame:
            break
    }
0
Shadros
   var strDateValidate = ""
            let dateFormatter = DateFormatter()
            dateFormatter.dateFormat = "yyyy-MM-dd"

            let firstDate = dateFormatter.date(from:lblStartTime.text!)
            let secondDate = dateFormatter.date(from:lblEndTime.text!)

            if firstDate?.compare(secondDate!) == .orderedSame || firstDate?.compare(secondDate!) == .orderedAscending {
                print("Both dates are same or first is less than scecond")
                strDateValidate = "yes"
            }
            else
            {
                //second date is bigger than first
                strDateValidate = "no"
            }

            if strDateValidate == "no"
            {
                alertView(message: "Start date and end date for a booking must be equal or Start date must be smaller than the end date", controller: self)
            }
0