比较没有时间分量的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
NSDateComponents
与NSCalendar
结合使用。
根据我的经验,大多数人使用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中使用这个示例的示例,请参阅此答案:
我写了一个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。