Swift 3-Comparación de objetos de fecha


Estoy actualizando mi aplicación a la sintaxis Swift 3.0 (sé que todavía está en beta, pero quiero estar preparado tan pronto como se lance).

Hasta la Beta anterior de Xcode (Beta 5) pude comparar dos objetos Date usando los operandos <, > y ==. Pero en la última beta (Beta 6) esto ya no funciona. Aquí están algunas capturas de pantalla:

introduzca la descripción de la imagen aquí introduzca la descripción de la imagen aquí

Como puede ver en ambas capturas de pantalla, estos son dos objetos Date. Pero entiendo error de seguimiento: introduzca la descripción de la imagen aquí

¿Qué estoy haciendo mal? Las funciones todavía se declaran en la clase Date:

static func >(Date, Date)

Devuelve true si la Fecha de la mano izquierda es posterior a la Fecha de la mano derecha.

¿Es esto solo un error Beta o estoy haciendo algo mal?

Author: NinjaDeveloper, 2016-08-18

10 answers

He probado este fragmento en XCode 8 beta 6, y está funcionando bien.

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

if date1 == date2
{
}
else if date1 > date2
{
}
else if date1 < date2
{
}
 113
Author: Ankit Thakur,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-18 13:12:41

Date es Comparable & Equatable (a partir de Swift 3)

Esta respuesta complementa la respuesta de @Ankit Thakur.

Desde Swift 3 la estructura Date (basada en la clase NSDate subyacente) adopta la Comparable y Equatable protocolos.

  • Comparable requiere que Date implementar los operadores: <, <=, >, >=.
  • Equatable requiere que Date implemente el operador ==.
  • Equatable permite a Date utilizar la implementación predeterminada de el operador != (que es el inverso de la Equatable == operator implementation).

El siguiente código de ejemplo ejerce estos operadores de comparación y confirma qué comparaciones son verdaderas con las sentencias print.

Función de comparación

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

Uso de la muestra

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
 32
Author: Mobile Dan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-02 22:42:46

En Swift 3, La fecha es Comparable por lo que podemos comparar directamente fechas como

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

let isGreater = date1 > date2
print(isGreater)

let isSmaller = date1 < date2
print(isSmaller)

let isEqual = date1 == date2
print(isEqual)
 20
Author: Suhit Patil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-21 10:39:56

Mira esto http://iswift.org/cookbook/compare-2-dates

Obtener fechas:

// Get current date
let dateA = NSDate()

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

Usando la instrucción 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")
}

Usando la Instrucción IF

 if datePickerTo.date.compare(datePicker.date) == .orderedAscending {
     datePickerTo.date = datePicker.date
 }
 12
Author: Luis Abreu Acevedo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-23 01:53:30

Para mí el problema era que tenía mi propia clase extension to Date que definía todos los operadores de comparación. Ahora (ya que swift 3) esa fecha es comparable, estas extensiones no son necesarias. Así que los comenté y funcionó.

 9
Author: Jitendra Kulkarni,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-05 00:44:41

SWIFT 3: No sé si esto es lo que estás buscando. Pero comparo una cadena con una marca de tiempo actual para ver si mi cadena es más antigua que ahora.

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

Para usarlo:

if (checkTimeStamp(date:"2016-11-21 12:00:00") == false) {
    // Do something
}
 4
Author: N.B,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-21 16:06:33

Para comparar la fecha solo con el año-mes-día y sin tiempo para mí funcionó así:

     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
Author: Alessandro Mattiuzzi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-11 15:56:35

En el momento de escribir este artículo, Swift admite de forma nativa la comparación de Fechas con todos los operadores de comparación (i. e.<, <=, ==, >=, y >). También puede comparar fechas opcionales, pero están limitadas a <, ==, y >. Si necesita comparar dos fechas opcionales usando <= o >=, es decir,

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

Puede sobrecargar los operadores <= y >=para soportar opcionales:

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
Author: NSExceptional,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-12 20:11:43
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) }
 0
Author: Arjun Patel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-10-05 06:12:34

Otra forma de hacerlo:

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

        case .orderedDescending:
            break;

        case .orderedSame:
            break
    }
 0
Author: Shadros,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-10-05 07:03:50