Swift 3-比较日期对象


95

我正在将我的应用程序更新为Swift 3.0语法(我知道它仍处于beta版本,但我希望在发布时尽快做好准备)。

直到Xcode中(测试版5)的以前的测试,我能够比较两个Date使用操作数的对象<>==。但在最新的Beta(测试版6)中,此功能不再起作用。以下是一些屏幕截图:

在此处输入图片说明 在此处输入图片说明

正如您在两个屏幕截图中所看到的,这是两个Date对象。但是我收到以下错误: 在此处输入图片说明

我究竟做错了什么?这些函数仍在Date类中声明:

static func >(Date, Date)

如果左侧日期晚于右侧日期,则返回true。

这只是一个Beta错误还是我做错了什么?


2
let d1 = Date() ; let d2 = Date() ; if d1 > d2 { }在我的Xcode 8测试版6.作品
马丁- [R

1
是。–您应在“报告”导航器中查找完整的错误消息。
马丁R

谢谢@MartinR!不知道我可以“潜入”错误并获取更多信息。对我有很大帮助!
beeef

接受正确答案
Ankit Thakur

Answers:


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

DateComparableEquatable(从Swift 3开始)

此答案是@Ankit Thakur的答案的补充。

从Swift 3开始,Date结构(基于基础NSDate类)采用ComparableEquatable协议。

  • 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

Swift 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类扩展,它定义了所有比较运算符。现在(由于迅速3)日期是可比较的,因此不需要这些扩展名。所以我把它们注释掉了,并且奏效了。


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)->布尔

如果是同一天,请比较示例:

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

1

在编写这本书的时候,斯威夫特原生支持比较所有比较操作的日期(即<<===>=,和>)。您还可以比较可选日期,但仅限于<==>。如果需要使用<=或比较两个可选日期>=,即

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)如果使用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 

我不确定还是第二种选择可以100%使用。但是我将不更改firstStringDate和secondStringDate的值多少,结果是正确的。


1

在Swift 3,4中,您应该使用“比较”。例如:

DateArray.sort { (($0)?.compare($1))! == .orderedDescending }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.