Aktualizuję moją aplikację do składni Swift 3.0 (wiem, że wciąż jest w wersji beta, ale chcę być przygotowany, gdy tylko zostanie wydany).
Aż do poprzedniej wersji beta Xcode (beta 5) udało mi się porównanie dwóch Date
obiektów za pomocą argumentów <
, >
a ==
. Ale w najnowszej wersji beta (Beta 6) to już nie działa. Oto kilka zrzutów ekranu:
Jak widać na obu zrzutach ekranu, są to dwa Date
obiekty. Ale pojawia się następujący błąd:
Co ja robię źle? Funkcje są nadal deklarowane w Date
klasie:
static func >(Date, Date)
Zwraca wartość true, jeśli data po lewej stronie jest późniejsza niż data po prawej stronie.
Czy to tylko błąd Beta, czy robię coś nie tak?
let d1 = Date() ; let d2 = Date() ; if d1 > d2 { }
działa w mojej Xcode 8 beta 6.Odpowiedzi:
Wypróbowałem ten fragment (w Xcode 8 Beta 6) i działa dobrze.
let date1 = Date() let date2 = Date().addingTimeInterval(100) if date1 == date2 { ... } else if date1 > date2 { ... } else if date1 < date2 { ... }
źródło
2019-05-14 12:08:14 +0000
==2019-05-14
powinno zwrócić prawdę. co wtedy?Date
toComparable
&Equatable
(od Swift 3)Ta odpowiedź uzupełnia odpowiedź @Ankit Thakur.
Od wersji Swift 3
Date
struktura (oparta naNSDate
klasie bazowej ) przyjmuje protokołyComparable
iEquatable
.Comparable
wymagaDate
wdrożenia operatorów:<
,<=
,>
,>=
.Equatable
wymagaDate
wdrożenia==
operatora.Equatable
pozwalaDate
na użycie domyślnej implementacji!=
operatora (która jest odwrotnościąEquatable
==
implementacji operatora).Poniższy przykładowy kod sprawdza te operatory porównania i potwierdza, które porównania są prawdziwe z
print
instrukcjami.Funkcja porównania
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: ", ") }
Przykładowe użycie
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
źródło
od wersji Swift 3 i nowszych Data jest porównywalna, dzięki czemu możemy bezpośrednio porównywać daty, takie jak
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)
Alternatywnie możemy utworzyć rozszerzenie w dniu
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 } }
Posługiwać się:
let isEqual = date1.isEqualTo(date2)
źródło
2019-05-14 12:08:14 +0000
==2019-05-14
powinno zwrócić prawdę. co wtedy?Spójrz na http://iswift.org/cookbook/compare-2-dates
Pobierz daty:
// Get current date let dateA = NSDate() // Get a later date (after a couple of milliseconds) let dateB = NSDate()
Korzystanie z instrukcji 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") }
przy użyciu instrukcji IF
if dateA.compare(dateB) == .orderedAscending { datePickerTo.date = datePicker.date } //OR if case .orderedAcending = dateA.compare(dateB) { }
źródło
Dla mnie problem polegał na tym, że miałem własne rozszerzenie klasy Date, które definiowało wszystkie operatory porównania. Teraz (od swift 3), że Date jest porównywalna, te rozszerzenia nie są potrzebne. Więc skomentowałem je i zadziałało.
źródło
SWIFT 3: Nie wiem, czy tego właśnie szukasz. Ale porównuję ciąg z bieżącym znacznikiem czasu, aby sprawdzić, czy mój ciąg jest teraz starszy.
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 } }
Aby z niego skorzystać:
if (checkTimeStamp(date:"2016-11-21 12:00:00") == false) { // Do something }
źródło
Jeśli chcesz na przykład zignorować sekundy, możesz użyć
func isDate (Date, equalTo: Date, toUnitGranularity: NSCalendar.Unit) -> Bool
Przykładowe porównanie, jeśli jest tego samego dnia:
Calendar.current.isDate(date1, equalTo: date2, toGranularity: .day)
źródło
Aby porównać datę tylko z rokiem - miesiącem - dniem i bez czasu u mnie działało tak:
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)") }
źródło
Począwszy od chwili pisania tego tekstu, Swift natywnie obsługuje porównywanie dat z wszystkich operatorów porównania (to znaczy
<
,<=
,==
,>=
, i>
). Można również porównać opcjonalnymi terminami ale są ograniczone do<
,==
, i>
. Jeśli chcesz porównać dwie opcjonalne daty za pomocą<=
lub>=
, tjlet date1: Date? = ... let date2: Date? = ... if date1 >= date2 { ... }
Możesz przeciążać plik
<=
>=
operatory i , aby obsługiwać opcje: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 }
źródło
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) }
źródło
Inny sposób na zrobienie tego:
switch date1.compare(date2) { case .orderedAscending: break case .orderedDescending: break; case .orderedSame: break }
źródło
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) }
źródło
Swift 5:
1) Jeśli używasz typu daty:
let firstDate = Date() let secondDate = Date() print(firstDate > secondDate) print(firstDate < secondDate) print(firstDate == secondDate)
2) Jeśli używasz typu String:
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
Nie jestem pewien lub druga opcja działa na 100%. Ale o ile nie zmieniłbym wartości firstStringDate i secondStringDate, wynik był poprawny.
źródło
w Swift 3,4 należy użyć opcji „Porównaj”. na przykład:
DateArray.sort { (($0)?.compare($1))! == .orderedDescending }
źródło