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?

beeef
sumber
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 { ... }
Ankit Thakur
sumber
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
Ponsel Dan
sumber
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)

Suhit Patil
sumber
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) {

 }
Luis Abreu Acevedo
sumber
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.

Jitendra Kulkarni
sumber
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
}
NB
sumber
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)")
                        }
Alessandro Mattiuzzi
sumber
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)
zdravko zdravkin
sumber
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
}
NSExceptional
sumber
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) }
Arjun Patel
sumber
1

Cara lain untuk melakukannya:

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

        case .orderedDescending:
            break;

        case .orderedSame:
            break
    }
Shadros
sumber
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)
            }
Davender Verma
sumber
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.

maxwell
sumber
1

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

DateArray.sort { (($0)?.compare($1))! == .orderedDescending }
Alireza
sumber