ios - color - Swift 3-Comparar objetos de fecha
navigationitem title color (12)
Date
es
Comparable
y
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 los protocolos
Comparable
y
Equatable
.
-
Comparable
requiere queDate
implemente los operadores:<
,<=
,>
,>=
. -
Equatable
requiere queDate
implemente el operador==
. -
Equatable
permite queDate
use la implementación predeterminada del operador!=
(Que es el inverso de la implementación del operadorEquatable
==
).
El siguiente código de ejemplo ejercita estos operadores de comparación y confirma qué comparaciones son verdaderas con
print
declaraciones de
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 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
Estoy actualizando mi aplicación a la sintaxis de Swift 3.0 (sé que todavía está en versión beta, pero quiero estar preparado tan pronto como se lance).
Hasta la versión beta anterior de Xcode (Beta 5) pude comparar dos objetos
Date
usando los operandos
<
,
>
y
==
.
Pero en la última versión beta (Beta 6) esto ya no funciona.
Aquí hay algunas capturas de pantalla:
Como puede ver en ambas capturas de pantalla, estos son dos objetos
Date
.
Pero me sale el siguiente error:
¿Qué estoy haciendo mal?
Las funciones aún se declaran en la clase
Date
:
static func >(Date, Date)
Devuelve verdadero si la fecha de la izquierda es posterior en el tiempo a la fecha de la derecha.
¿Es solo un error Beta o estoy haciendo algo mal?
Al momento de escribir esto, Swift admite de forma nativa las fechas de comparación con todos los operadores de comparación (es decir,
<=
,
<=
,
==
,
>=
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 admitir opciones:
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
}
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 { ... }
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()
Uso de la declaració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")
}
utilizando la declaración IF
if dateA.compare(dateB) == .orderedAscending {
datePickerTo.date = datePicker.date
}
//OR
if case .orderedAcending = dateA.compare(dateB) {
}
Otra forma de hacerlo:
switch date1.compare(date2) {
case .orderedAscending:
break
case .orderedDescending:
break;
case .orderedSame:
break
}
Para comparar la fecha solo con año - mes - día y sin tiempo para mí, trabajé 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)")
}
Para mí, el problema era que tenía mi propia extensión para la clase Fecha que definía todos los operadores de comparación. Ahora (desde swift 3) esa Fecha es comparable, estas extensiones no son necesarias. Así que los comenté y funcionó.
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
}
desde Swift 3 y superior, la fecha es comparable para que podamos 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)
Alternativamente, podemos crear una extensión en Fecha
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
}
}
Uso:
let isEqual = date1.isEqualTo(date2)
Swift 5:
1) Si usa el tipo de fecha:
let firstDate = Date()
let secondDate = Date()
print(firstDate > secondDate)
print(firstDate < secondDate)
print(firstDate == secondDate)
2) Si usa el tipo de cadena:
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
No estoy seguro o la segunda opción funciona al 100%. Pero, ¿cuánto no cambiaría los valores de firstStringDate y secondStringDate? El resultado fue correcto.
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) }
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)
}