Swift 3 - 比较日期对象
Swift 3 - Comparing Date objects
我正在将我的应用程序更新到 Swift 3.0 语法(我知道它仍处于测试阶段,但我想在它发布后立即做好准备)。
直到上一个 Xcode 测试版(Beta 5)我才能够使用操作数 <
、>
和 [=14= 来比较两个 Date
对象].但在最新的测试版(Beta 6)中,这不再有效。以下是一些截图:
如您在两个屏幕截图中所见,这是两个 Date
对象。但我收到以下错误:
我做错了什么?这些函数仍然在 Date
class:
中声明
static func >(Date, Date)
Returns true if the left hand Date is later in time than the right hand Date.
这只是一个测试版错误还是我做错了什么?
我已经尝试过这个片段(在 Xcode 8 Beta 6 中),它工作正常。
let date1 = Date()
let date2 = Date().addingTimeInterval(100)
if date1 == date2 { ... }
else if date1 > date2 { ... }
else if date1 < date2 { ... }
不要使用比较器 <
、>
、==
、!=
。
使用 compare(_ other: Date)
函数。
用法
// Get current date
let dateA = Date()
// Get a later date (after a couple of milliseconds)
let dateB = Date()
// Compare them using switch
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")
}
// Compare them using if
if dateA.compare(dateB) == .orderedAscending {
datePickerTo.date = datePicker.date
}
对我来说,问题是我有自己的 Date class 扩展,它定义了所有比较运算符。现在(因为 swift 3) Date 是可比较的,不需要这些扩展。所以我把它们注释掉了,它起作用了。
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
}
从 Swift 3 及以上,Date 是 Comparable 所以我们可以直接比较日期
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)
或者我们可以在 Date
上创建扩展
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)
Date
是 Comparable
& Equatable
(截至 Swift 3)
这个答案补充了@Ankit Thakur 的答案。
因为 Swift 3 Date
结构(基于底层 NSDate
class)采用了 Comparable
and 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
只比较日期与年 - 月 - 日并且没有时间对我来说是这样工作的:
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)")
}
截至撰写本文时,Swift 原生支持使用所有比较运算符(即 <
、<=
、==
、>=
,以及 >
)。您还可以比较可选日期,但仅限于 <
、==
和 >
。如果您需要使用 <=
或 >=
比较两个可选日期,即
let date1: Date? = ...
let date2: Date? = ...
if date1 >= date2 { ... }
您可以重载 <=
和 >=
运算符以支持可选值:
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
}
extension Date {
func isBetween(_ date1: Date, and date2: Date) -> Bool {
return (min(date1, date2) ... max(date1, date2)).contains(self)
}
}
let resultArray = dateArray.filter { [=10=].dateObj!.isBetween(startDate, and: endDate) }
另一种方法:
switch date1.compare(date2) {
case .orderedAscending:
break
case .orderedDescending:
break;
case .orderedSame:
break
}
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)
}
Swift 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 的值结果是正确的。
在 Swift 3,4 你应该使用 "Compare"。
例如:
DateArray.sort { (([=10=])?.compare())! == .orderedDescending }
例如,如果您想忽略秒数
你可以使用
func isDate(Date, equalTo: Date, toUnitGranularity: NSCalendar.Unit) -> Bool
比较是否是同一天的例子:
Calendar.current.isDate(date1, equalTo: date2, toGranularity: .day)
我正在将我的应用程序更新到 Swift 3.0 语法(我知道它仍处于测试阶段,但我想在它发布后立即做好准备)。
直到上一个 Xcode 测试版(Beta 5)我才能够使用操作数 <
、>
和 [=14= 来比较两个 Date
对象].但在最新的测试版(Beta 6)中,这不再有效。以下是一些截图:
如您在两个屏幕截图中所见,这是两个 Date
对象。但我收到以下错误:
我做错了什么?这些函数仍然在 Date
class:
static func >(Date, Date)
Returns true if the left hand Date is later in time than the right hand Date.
这只是一个测试版错误还是我做错了什么?
我已经尝试过这个片段(在 Xcode 8 Beta 6 中),它工作正常。
let date1 = Date()
let date2 = Date().addingTimeInterval(100)
if date1 == date2 { ... }
else if date1 > date2 { ... }
else if date1 < date2 { ... }
不要使用比较器 <
、>
、==
、!=
。
使用 compare(_ other: Date)
函数。
用法
// Get current date
let dateA = Date()
// Get a later date (after a couple of milliseconds)
let dateB = Date()
// Compare them using switch
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")
}
// Compare them using if
if dateA.compare(dateB) == .orderedAscending {
datePickerTo.date = datePicker.date
}
对我来说,问题是我有自己的 Date class 扩展,它定义了所有比较运算符。现在(因为 swift 3) Date 是可比较的,不需要这些扩展。所以我把它们注释掉了,它起作用了。
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
}
从 Swift 3 及以上,Date 是 Comparable 所以我们可以直接比较日期
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)
或者我们可以在 Date
上创建扩展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)
Date
是 Comparable
& Equatable
(截至 Swift 3)
这个答案补充了@Ankit Thakur 的答案。
因为 Swift 3 Date
结构(基于底层 NSDate
class)采用了 Comparable
and 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
只比较日期与年 - 月 - 日并且没有时间对我来说是这样工作的:
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)")
}
截至撰写本文时,Swift 原生支持使用所有比较运算符(即 <
、<=
、==
、>=
,以及 >
)。您还可以比较可选日期,但仅限于 <
、==
和 >
。如果您需要使用 <=
或 >=
比较两个可选日期,即
let date1: Date? = ...
let date2: Date? = ...
if date1 >= date2 { ... }
您可以重载 <=
和 >=
运算符以支持可选值:
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
}
extension Date {
func isBetween(_ date1: Date, and date2: Date) -> Bool {
return (min(date1, date2) ... max(date1, date2)).contains(self)
}
}
let resultArray = dateArray.filter { [=10=].dateObj!.isBetween(startDate, and: endDate) }
另一种方法:
switch date1.compare(date2) {
case .orderedAscending:
break
case .orderedDescending:
break;
case .orderedSame:
break
}
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)
}
Swift 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 的值结果是正确的。
在 Swift 3,4 你应该使用 "Compare"。 例如:
DateArray.sort { (([=10=])?.compare())! == .orderedDescending }
例如,如果您想忽略秒数 你可以使用
func isDate(Date, equalTo: Date, toUnitGranularity: NSCalendar.Unit) -> Bool
比较是否是同一天的例子:
Calendar.current.isDate(date1, equalTo: date2, toGranularity: .day)