比较没有时间分量的NSDates

在一个快速的操场上,我一直在使用

NSDate.date() 

但是,这总是伴随着时间元素出现。 对于我的应用程序,我需要忽略时间元素。 这可能在Swift中吗? 如何做呢? 即使我可以将时间元素设置为每个date的同一时间也是如此。

此外,我试图比较两个date,目前我使用下面的代码:

 var earlierDate:NSDate = firstDate.earlierDate(secondDate) 

这是唯一的方法,或者我可以这样做,忽略时间元素? 例如,如果他们是同一天,但不同的时间,我不想要一个结果。

使用这个NSCalendar函数来比较iOS 8.0+中的date

 func compareDate(date1: NSDate, toDate date2: NSDate, toUnitGranularity unit: NSCalendarUnit) -> NSComparisonResult 

.Day为单位

使用这个function如下:

 let now = NSDate() // "Sep 23, 2015, 10:26 AM" let olderDate = NSDate(timeIntervalSinceNow: -10000) // "Sep 23, 2015, 7:40 AM" var order = NSCalendar.currentCalendar().compareDate(now, toDate: olderDate, toUnitGranularity: .Hour) switch order { case .OrderedDescending: print("DESCENDING") case .OrderedAscending: print("ASCENDING") case .OrderedSame: print("SAME") } // Compare to hour: DESCENDING order = NSCalendar.currentCalendar().compareDate(now, toDate: olderDate, toUnitGranularity: .Day) switch order { case .OrderedDescending: print("DESCENDING") case .OrderedAscending: print("ASCENDING") case .OrderedSame: print("SAME") } // Compare to day: SAME 

在iOS 8.0+中的NSCalendar中有几个有用的方法:

 startOfDayForDate, isDateInToday, isDateInYesterday, isDateInTomorrow 

甚至比较几天:

 func isDate(date1: NSDate!, inSameDayAsDate date2: NSDate!) -> Bool 

要忽略时间元素,你可以使用这个:

 var toDay = NSCalendar.currentCalendar().startOfDayForDate(NSDate()) 

但是,如果你还必须支持iOS 7,你总是可以写一个扩展

 extension NSCalendar { func myStartOfDayForDate(date: NSDate!) -> NSDate! { let systemVersion:NSString = UIDevice.currentDevice().systemVersion if systemVersion.floatValue >= 8.0 { return self.startOfDayForDate(date) } else { return self.dateFromComponents(self.components(.CalendarUnitYear | .CalendarUnitMonth | .CalendarUnitDay, fromDate: date)) } } } 

两个date比较迅速。

  // Date comparision to compare current date and end date. var dateComparisionResult:NSComparisonResult = currentDate.compare(endDate) if dateComparisionResult == NSComparisonResult.OrderedAscending { // Current date is smaller than end date. } else if dateComparisionResult == NSComparisonResult.OrderedDescending { // Current date is greater than end date. } else if dateComparisionResult == NSComparisonResult.OrderedSame { // Current date and end date are same. } 

我写了以下方法,通过从Ashley Mills解决scheme中借用来比较两个date。 它比较两个date,如果两个date是相同的(剥离时间),则返回true。

 func compareDate(date1:NSDate, date2:NSDate) -> Bool { let order = NSCalendar.currentCalendar().compareDate(date1, toDate: date2, toUnitGranularity: .Day) switch order { case .OrderedSame: return true default: return false } } 

它被这样调用:

 if compareDate(today, date2: anotherDate) { // The two dates are on the same day. } 

对于iOS7的支持

 let dateFormatter = NSDateFormatter() dateFormatter.dateFormat = "yyyy-MM-dd" let date1String = dateFormatter.stringFromDate(date1) let date2String = dateFormatter.stringFromDate(date2) if date1String == date2String { println("Equal date") } 

你可以用它的描述来比较两个date。

 let date1 = NSDate() let date2 = NSDate(timeIntervalSinceNow: 120) if date1.description == date2.description { print(true) } else { print(false) // false (I have added 2 seconds between them) } 

如果您想将date的时间元素设置为不同的时间,可以按照以下步骤操作:

 extension NSDate { struct Calendar { static let gregorian = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)! } var day: Int { return Calendar.gregorian.component(.Day, fromDate: self) } var month: Int { return Calendar.gregorian.component(.Month, fromDate: self) } var year: Int { return Calendar.gregorian.component(.Year, fromDate: self) } var noon: NSDate { return Calendar.gregorian.dateWithEra(1, year: year, month: month, day: day, hour: 12, minute: 0, second: 0, nanosecond: 0)! } } let date1 = NSDate() let date2 = NSDate(timeIntervalSinceNow: 120) print(date1.noon == date2.noon) // true 

或者你也可以使用NSDateFormatter来做到这一点:

 extension NSDate { struct Date { static let formatterYYYYMMDD: NSDateFormatter = { let formatter = NSDateFormatter() formatter.dateFormat = "yyyyMMdd" return formatter }() } var yearMonthDay: String { return Date.formatterYYYYMMDD.stringFromDate(self) } func isSameDayAs(date:NSDate) -> Bool { return yearMonthDay == date.yearMonthDay } } let date1 = NSDate() let date2 = NSDate(timeIntervalSinceNow: 120) print(date1.yearMonthDay == date2.yearMonthDay) // true print(date1.isSameDayAs(date2)) // true 

另一个选项(iOS8 +)是使用日历方法isDate(inSameDayAsDate :):

 extension NSDate { struct Calendar { static let gregorian = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)! } func isInSameDayAs(date date: NSDate) -> Bool { return Calendar.gregorian.isDate(self, inSameDayAsDate: date) } } let date1 = NSDate() let date2 = NSDate(timeIntervalSinceNow: 120) if date1.isInSameDayAs(date: date2 ){ print(true) // true } else { print(false) } 

在Swift 4:

 func compareDate(date1:Date, date2:Date) -> Bool { let order = NSCalendar.current.compare(date1, to: date2, toGranularity: .day) switch order { case .orderedSame: return true default: return false } } 

迅速:

 extension NSDate { /** Compares current date with the given one down to the seconds. If date==nil, then always return false :param: date date to compare or nil :returns: true if the dates has equal years, months, days, hours, minutes and seconds. */ func sameDate(date: NSDate?) -> Bool { if let d = date { let calendar = NSCalendar.currentCalendar() if NSComparisonResult.OrderedSame == calendar.compareDate(self, toDate: d, toUnitGranularity: NSCalendarUnit.SecondCalendarUnit) { return true } } return false } } 

对于Swift3

 var order = NSCalendar.current.compare(firstDate, to: secondDate, toGranularity: .hour) if order == .orderedSame { //Both the dates are same. //Your Logic. } 

Swift 3

  let order = NSCalendar.current.compare(date1, to: date2, toGranularity: .day) if order == .orderedAscending { // date 1 is older } else if order == .orderedDescending { // date 1 is newer } else if order == .orderedSame { // same day/hour depending on granularity parameter } 

当您在操场上的NSDate.date()时,您会看到打印的默认说明 。 使用NSDateFormatter打印date对象的本地化描述,可能只有date部分。

要将date的特定部分清零(为了比较起见), NSCalendar NSDateComponentsNSCalendar结合使用。

根据我的经验,大多数人使用NSDate的问题都来自错误的假设,即NSDate可以用来表示“正常”意义上的date(即从当地时区午夜开始的24周期)。 在正常(日常/非程序)使用情况下,2014年1月1日在伦敦与北京或纽约的1月1日是同一date, 即使它们实时覆盖不同时期 。 为了达到这个极限,圣诞岛上的时间是UTC + 14,而中途岛上的时间是UTC-11。 因此,2014年1月1日在这两个岛上的date是相同的,尽pipe直到另一个小时完成一个小时才开始。

如果这是你正在录制的datetypes(如果你不logging时间组件,它可能是),那么不要使用NSDate(它只存储了2001-01-01 00:00 UTC的时间,没有别的)但将年份和月份存储为整数(可能是通过创build自己的包装这些值的CivilDate类),然后使用它来代替。

只需进入NSDate来比较date,然后确保在两个NSDate上显式声明时区为“UTC”,以便进行比较。

Swift iOS 8及更高版本当您不仅仅需要更大或更小的date比较时。 例如,是同一天还是前一天,…

 extension Date { func compareTo(date: Date, toGranularity: Calendar.Component ) -> ComparisonResult { var cal = Calendar.current cal.timeZone = TimeZone(identifier: "Europe/Paris")! return cal.compare(self, to: date, toGranularity: toGranularity) } } 

有关如何在filter中使用这个示例的示例,请参阅此答案:

https://stackoverflow.com/a/45746206/4946476

我写了一个Swift 4扩展来比较两个date:

 import Foundation extension Date { func isSameDate(_ comparisonDate: Date) -> Bool { let order = Calendar.current.compare(self, to: comparisonDate, toGranularity: .day) return order == .orderedSame } func isBeforeDate(_ comparisonDate: Date) -> Bool { let order = Calendar.current.compare(self, to: comparisonDate, toGranularity: .day) return order == .orderedAscending } func isAfterDate(_ comparisonDate: Date) -> Bool { let order = Calendar.current.compare(self, to: comparisonDate, toGranularity: .day) return order == .orderedDescending } } 

用法:

startDate.isSameDateAs(endDate) // returns a true or false

回答你的问题:

这可能在Swift中吗?

对的,这是可能的


啊,你还想现在怎么样

 let cal = NSCalendar.currentCalendar() cal.rangeOfUnit(.DayCalendarUnit, startDate: &d1, interval: nil, forDate: d1) // d1 NSDate? cal.rangeOfUnit(.DayCalendarUnit, startDate: &d2, interval: nil, forDate: d2) // d2 NSDate? 

现在,d1和d2将包含他们日子的开始date。

d1!.compare(d2!)

要显示它们没有时间部分,我们NSDateFormatter。