Swift 3 - Membandingkan objek Tanggal


95

Saya memperbarui aplikasi saya ke sintaks Swift 3.0 (saya tahu ini masih dalam versi beta tetapi saya ingin bersiap segera setelah dirilis).

Hingga Beta Xcode sebelumnya (Beta 5) saya dapat membandingkan dua Dateobjek menggunakan operan <, >dan ==. Tetapi dalam versi beta terbaru (Beta 6) ini tidak berfungsi lagi. Berikut beberapa tangkapan layarnya:

masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini

Seperti yang Anda lihat di kedua tangkapan layar, ini adalah dua Dateobjek. Tetapi saya mendapatkan kesalahan berikut: masukkan deskripsi gambar di sini

Apa yang saya lakukan salah? Fungsinya masih dideklarasikan di Datekelas:

static func >(Date, Date)

Mengembalikan nilai benar jika Tanggal di sisi kiri lebih lambat dari Tanggal di sisi kanan.

Apakah ini hanya bug Beta atau apakah saya melakukan sesuatu yang salah?


2
let d1 = Date() ; let d2 = Date() ; if d1 > d2 { }bekerja di Xcode 8 beta 6.
Martin R

1
Iya. - Anda harus mencari pesan kesalahan lengkap di navigator Laporan.
Martin R

Terima kasih @MartinR! Tidak tahu bahwa saya dapat "menyelami" suatu kesalahan dan mendapatkan informasi lebih lanjut. Banyak membantu saya!
Beeef

menerima jawaban yang benar
Ankit Thakur

Jawaban:


161

Saya telah mencoba potongan ini (di Xcode 8 Beta 6), dan berfungsi dengan baik.

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

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

jika saya ingin mengabaikan waktu. misalnya 2019-05-14 12:08:14 +0000== 2019-05-14harus mengembalikan nilai true. lalu apa ?
Awais Fayyaz

@AwaisFayyaz Jika Anda ingin membandingkan tanggal tanpa memperhitungkan DateComponent. Anda perlu mendapatkan komponen yang Anda inginkan sejak tanggal. Kemudian dapatkan tanggal dari DateComponents dan bandingkan mereka.
Giorgio Doganiero

52

Dateadalah Comparable& Equatable(pada Swift 3)

Jawaban ini melengkapi jawaban @Ankit Thakur.

Sejak Swift 3, Datestruct (berdasarkan NSDatekelas yang mendasarinya ) mengadopsi protokol Comparabledan Equatable.

  • Comparablemembutuhkan yang Datemenerapkan operator: <, <=, >, >=.
  • Equatablemensyaratkan bahwa Datemengimplementasikan ==operator.
  • Equatablememungkinkan Dateuntuk menggunakan implementasi default dari !=operator (yang merupakan kebalikan dari Equatable ==implementasi operator).

Kode contoh berikut melatih operator perbandingan ini dan mengonfirmasi perbandingan mana yang benar dengan printpernyataan.

Fungsi perbandingan

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

Penggunaan Sampel

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

31

dari Swift 3 ke atas, Date is Comparable sehingga kita bisa langsung membandingkan tanggal seperti itu

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)

Atau Kami dapat membuat ekstensi pada Tanggal

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

Menggunakan: let isEqual = date1.isEqualTo(date2)


jika saya ingin mengabaikan waktu. misalnya 2019-05-14 12:08:14 +0000== 2019-05-14harus mengembalikan nilai true. lalu apa ?
Awais Fayyaz

16

Lihat http://iswift.org/cookbook/compare-2-dates ini

Dapatkan Tanggal:

// Get current date
let dateA = NSDate()

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

Menggunakan Pernyataan 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")
}

menggunakan Pernyataan IF

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

 //OR

 if case .orderedAcending = dateA.compare(dateB) {

 }

9

Bagi saya masalahnya adalah saya memiliki ekstensi saya sendiri untuk kelas Date yang mendefinisikan semua operator pembanding. Sekarang (sejak swift 3) Tanggal itu sebanding, ekstensi ini tidak diperlukan. Jadi saya berkomentar dan berhasil.


8

SWIFT 3: Tidak tahu apakah ini yang Anda cari. Tapi saya membandingkan string dengan stempel waktu saat ini untuk melihat apakah string saya lebih tua dari sekarang.

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

Untuk menggunakannya:

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

5

Untuk membandingkan tanggal hanya dengan tahun - bulan - hari dan tanpa waktu bagi saya bekerja seperti ini:

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

5

Jika Anda ingin mengabaikan detik misalnya, Anda dapat menggunakan

func isDate (Date, equalTo: Date, toUnitGranularity: NSCalendar.Unit) -> Bool

Contoh bandingkan jika itu hari yang sama:

Calendar.current.isDate(date1, equalTo: date2, toGranularity: .day)

1

Pada saat penulisan ini, Swift dukungan native membandingkan Tanggal dengan semua operator perbandingan (yaitu <, <=, ==, >=, dan >). Anda juga dapat membandingkan Tanggal opsional tetapi terbatas pada <, ==, dan >. Jika Anda perlu membandingkan dua tanggal opsional menggunakan <=atau >=, yaitu

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

Anda dapat membebani operator <=dan >=untuk mendukung pilihan:

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

Cara lain untuk melakukannya:

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

        case .orderedDescending:
            break;

        case .orderedSame:
            break
    }

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

1

Cepat 5:

1) Jika Anda menggunakan tipe Tanggal:

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

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

2) Jika Anda menggunakan tipe 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 

Saya tidak yakin atau opsi kedua berfungsi pada 100%. Tapi berapa banyak saya tidak akan mengubah nilai firstStringDate dan secondStringDate hasilnya benar.


1

di Swift 3,4 Anda harus menggunakan "Bandingkan". sebagai contoh:

DateArray.sort { (($0)?.compare($1))! == .orderedDescending }
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.