Swift 3-日付オブジェクトの比較


94

アプリをSwift 3.0構文に更新しています(まだベータ版であることはわかっていますが、リリースされたらすぐに準備したいと考えています)。

Xcodeの以前のベータ版(ベータ5)まで、私は2つのを比較することができたDateオペランドを使用してオブジェクトを<>==。しかし、最新のベータ版(ベータ6)では、これはもう機能していません。ここにいくつかのスクリーンショットがあります:

ここに画像の説明を入力してください ここに画像の説明を入力してください

両方のスクリーンショットからわかるように、これらは2つのDateオブジェクトです。しかし、私は次のエラーを受け取ります: ここに画像の説明を入力してください

何が悪いのですか?関数は引き続きDateクラスで宣言されています。

static func >(Date, Date)

左側の日付が右側の日付より遅い場合にtrueを返します。

これは単なるベータ版のバグですか、それとも何か問題がありますか?


2
let d1 = Date() ; let d2 = Date() ; if d1 > d2 { }私のXcode 8ベータ6で動作します
マーティンR

1
はい。–レポートナビゲーターで完全なエラーメッセージを検索する必要があります。
マーティンR

@MartinRありがとうございます!エラーに「飛び込み」、詳細情報を入手できることを知りませんでした。とても助かりました!
ビーフ

正解を受け入れる
Ankit Thakur 2017

回答:


161

私はこのスニペット(Xcode 8 Beta 6)を試してみましたが、正常に動作しています。

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

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

時間を無視したい場合。たとえば、2019-05-14 12:08:14 +0000== 2019-05-14はtrueを返す必要があります。じゃあ何 ?
Awais Fayyaz

@AwaisFayyaz DateComponentを考慮せずに日付を比較する場合。日付から必要なコンポーネントを取得する必要があります。次に、DateComponentsから日付を取得して比較します。
Giorgio Doganiero

52

Dateis ComparableEquatable(Swift 3以降)

この回答は、@ Ankit Thakurの回答を補足するものです。

Swift 3以降、Date構造体(基になるNSDateクラスに基づく)はComparableおよびEquatableプロトコルを採用しています。

  • Comparableそれが必要とするDate演算子を実装しています<<=>>=
  • EquatableオペレーターをDate実装する必要があり==ます。
  • Equatable演算子のDateデフォルトの実装!=Equatable ==演算子の実装の逆)を使用できます。

次のサンプルコードは、これらの比較演算子を実行し、どの比較がprintステートメントで正しいかを確認します。

比較機能

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

サンプルの使用

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

スウィフト3以上、日付が同等である私たちは直接のような日付を比較することができますので、

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)

あるいは、日付に拡張を作成できます

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

使用する: let isEqual = date1.isEqualTo(date2)


時間を無視したい場合。たとえば、2019-05-14 12:08:14 +0000== 2019-05-14はtrueを返す必要があります。じゃあ何 ?
Awais Fayyaz

15

これを見てください http://iswift.org/cookbook/compare-2-dates

日付を取得:

// Get current date
let dateA = NSDate()

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

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

IFステートメントの使用

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

 //OR

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

 }

9

私にとっての問題は、すべての比較演算子を定義するDateクラスへの独自の拡張機能があったことです。現在(Swift 3以降)、Dateは比較可能であるため、これらの拡張機能は必要ありません。だから私はそれらをコメントアウトし、それはうまくいった。


7

SWIFT 3:これがあなたが探しているものかどうかわからない。しかし、文字列を現在のタイムスタンプと比較して、私の文字列がそれよりも古いかどうかを確認します。

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

それを使用するには:

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

5

年-月-日のみで、時間なしで日付を比較するには、次のようにしました:

     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

例えば秒を無視したいなら、あなたは使うことができます

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

例が同じ日かどうかを比較します。

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

1

これを書いている時点では、スウィフトネイティブサポートは、すべての比較演算子と日付を比較する(すなわち<<===>=、および>)。また、オプションの日付を比較することができますがこれらに限定されている<==><=またはを使用して2つのオプションの日付を比較する必要がある場合>=、つまり

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

<=and >=演算子をオーバーロードして、オプションをサポートできます。

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

それを行う別の方法:

    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

スウィフト5:

1)日付タイプを使用する場合:

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

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

2)文字列型を使用する場合:

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 

わからない、または2番目のオプションが100%で機能します。しかし、firstStringDateとsecondStringDateの値をどれだけ変更しないと、結果は正しかったでしょう。


1

Swift 3,4では「比較」を使用する必要があります。例えば:

DateArray.sort { (($0)?.compare($1))! == .orderedDescending }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.