如何确定是否NSDate是今天?
如何检查一个NSDate
属于今天?
我曾经使用[aDate description]
前10个字符来检查它。 [[aDate description] substringToIndex:10]
返回"YYYY-MM-DD"
这样的string,所以我把string与[[[NSDate date] description] substringToIndex:10]
返回的string进行了比较。
有更快和/或更简洁的方法来检查?
谢谢。
您可以比较date组件:
NSDateComponents *otherDay = [[NSCalendar currentCalendar] components:NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:aDate]; NSDateComponents *today = [[NSCalendar currentCalendar] components:NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:[NSDate date]]; if([today day] == [otherDay day] && [today month] == [otherDay month] && [today year] == [otherDay year] && [today era] == [otherDay era]) { //do stuff }
编辑:
我更喜欢斯蒂芬的方法,我认为这样做更清晰,更容易理解:
NSCalendar *cal = [NSCalendar currentCalendar]; NSDateComponents *components = [cal components:(NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:[NSDate date]]; NSDate *today = [cal dateFromComponents:components]; components = [cal components:(NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:aDate]; NSDate *otherDate = [cal dateFromComponents:components]; if([today isEqualToDate:otherDate]) { //do stuff }
克里斯,我已经纳入你的build议。 我不得不查看什么时代,所以对于不知道的人,区分BC和AD。 对于大多数人来说,这可能是不必要的,但是很容易检查并增加一些确定性,所以我已经包括了它。 如果你要加快速度,这可能不是一个好办法。
注意在SO上的许多答案,在7年后,这是完全过时的。 在Swift中,现在只需使用.isDateInToday
在MacOS 10.9+和iOS 8+中,NSCalendar / Calendar上有一个方法可以做到这一点!
- (BOOL)isDateInToday:(NSDate *)date
所以你只需要做
Objective-C的:
BOOL today = [[NSCalendar currentCalendar] isDateInToday:date];
Swift 3:
let today = Calendar.current.isDateInToday(date)
这是你的问题的分支,但是如果你想打印一个NSDate“今天”或“昨天”,使用函数
- (void)setDoesRelativeDateFormatting:(BOOL)b
为NSDateFormatter
我会尽量得到今天的date正常化到午夜和第二个date,正常化到午夜,然后比较,如果它是相同的NSDate。
从苹果公司的例子来看,你如何规范化到今天的午夜,在第二个date做同样的事情,并进行比较:
NSCalendar * gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSDateComponents * components = [gregorian components: (NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit) fromDate:[NSDate date]]; NSDate * today = [gregorian dateFromComponents:components];
没有必要玩弄组件,时代和东西。
NSCalendar提供了一个方法来获取一个现有date的某个时间单位的开始。
这段代码将得到今天和另一个date的开始,并比较。 如果它评估为NSOrderedSame
,那么这两个date都是在同一天 – 也就是今天。
NSDate *today = nil; NSDate *beginningOfOtherDate = nil; NSDate *now = [NSDate date]; [[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit startDate:&today interval:NULL forDate:now]; [[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit startDate:&beginningOfOtherDate interval:NULL forDate:beginningOfOtherDate]; if([today compare:beginningOfOtherDate] == NSOrderedSame) { //otherDate is a date in the current day }
工作Swift 3和4扩展了Catfish_Man的build议:
extension Date { func isToday() -> Bool { return Calendar.current.isDateInToday(self) } }
extension NSDate { func isToday() -> Bool { let cal = NSCalendar.currentCalendar() var components = cal.components([.Era, .Year, .Month, .Day], fromDate:NSDate()) let today = cal.dateFromComponents(components)! components = cal.components([.Era, .Year, .Month, .Day], fromDate:self) let otherDate = cal.dateFromComponents(components)! return today.isEqualToDate(otherDate) }
在Swift 2.0上为我工作
Swift版本的最佳答案:
let cal = NSCalendar.currentCalendar() var components = cal.components([.Era, .Year, .Month, .Day], fromDate:NSDate()) let today = cal.dateFromComponents(components)! components = cal.components([.Era, .Year, .Month, .Day], fromDate:aDate); let otherDate = cal.dateFromComponents(components)! if(today.isEqualToDate(otherDate)) { //do stuff }
您也可以检查您的date和当前date之间的时间间隔:
[myDate timeIntervalSinceNow]
这会给你myDate和当前date/时间之间的时间间隔,以秒为单位。
链接 。
编辑:大家注意:我很清楚[myDate timeIntervalSinceNow]不明确地确定是否myDate是今天。
我正在离开这个答案,所以如果有人正在寻找类似的东西,[myDate timeIntervalSinceNow]是有用的,他们可能会在这里find它。
请参阅Apple的文档条目“执行日历计算” [链接] 。
清单13在该页面上build议,要确定几天之间的夜间数量,可以使用:
- (NSInteger)midnightsFromDate:(NSDate *)startDate toDate:(NSDate *)endDate { NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar]; NSInteger startDay = [calendar ordinalityOfUnit:NSDayCalendarUnit inUnit:NSEraCalendarUnit forDate:startDate]; NSInteger endDay = [calendar ordinalityOfUnit:NSDayCalendarUnit inUnit:NSEraCalendarUnit forDate:endDate]; return endDay - startDay; }
然后,您可以通过使用该方法确定两天是否相同,并查看是否返回0。
Swift Extension基于最佳答案:
extension NSDate { func isToday() -> Bool { let cal = NSCalendar.currentCalendar() if cal.respondsToSelector("isDateInToday:") { return cal.isDateInToday(self) } var components = cal.components((.CalendarUnitEra | .CalendarUnitYear | .CalendarUnitMonth | .CalendarUnitDay), fromDate:NSDate()) let today = cal.dateFromComponents(components)! components = cal.components((.CalendarUnitEra | .CalendarUnitYear | .CalendarUnitMonth | .CalendarUnitDay), fromDate:self); let otherDate = cal.dateFromComponents(components)! return today.isEqualToDate(otherDate) } }
如果你有很多这样的date比较,那么调用calendar:components:fromDate
就要花费很多时间。 根据我所做的一些分析,他们似乎相当昂贵。
假设您正在尝试确定某些date数组,例如NSArray *datesToCompare
,与某天给定的date相同,比如说NSDate *baseDate
,那么您可以使用类似下面的内容(部分改编自上面的答案):
NSDate *baseDate = [NSDate date]; NSArray *datesToCompare = [NSArray arrayWithObjects:[NSDate date], [NSDate dateWithTimeIntervalSinceNow:100], [NSDate dateWithTimeIntervalSinceNow:1000], [NSDate dateWithTimeIntervalSinceNow:-10000], [NSDate dateWithTimeIntervalSinceNow:100000], [NSDate dateWithTimeIntervalSinceNow:1000000], [NSDate dateWithTimeIntervalSinceNow:50], nil]; // determine the NSDate for midnight of the base date: NSCalendar* calendar = [NSCalendar currentCalendar]; NSDateComponents* comps = [calendar components:(NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit) fromDate:baseDate]; NSDate* theMidnightHour = [calendar dateFromComponents:comps]; // set up a localized date formatter so we can see the answers are right! NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setDateStyle:NSDateFormatterMediumStyle]; [dateFormatter setTimeStyle:NSDateFormatterMediumStyle]; // determine which dates in an array are on the same day as the base date: for (NSDate *date in datesToCompare) { NSTimeInterval interval = [date timeIntervalSinceDate:theMidnightHour]; if (interval >= 0 && interval < 60*60*24) { NSLog(@"%@ is on the same day as %@", [dateFormatter stringFromDate:date], [dateFormatter stringFromDate:baseDate]); } else { NSLog(@"%@ is NOT on the same day as %@", [dateFormatter stringFromDate:date], [dateFormatter stringFromDate:baseDate]); } }
输出:
Nov 23, 2011 1:32:00 PM is on the same day as Nov 23, 2011 1:32:00 PM Nov 23, 2011 1:33:40 PM is on the same day as Nov 23, 2011 1:32:00 PM Nov 23, 2011 1:48:40 PM is on the same day as Nov 23, 2011 1:32:00 PM Nov 23, 2011 10:45:20 AM is on the same day as Nov 23, 2011 1:32:00 PM Nov 24, 2011 5:18:40 PM is NOT on the same day as Nov 23, 2011 1:32:00 PM Dec 5, 2011 3:18:40 AM is NOT on the same day as Nov 23, 2011 1:32:00 PM Nov 23, 2011 1:32:50 PM is on the same day as Nov 23, 2011 1:32:00 PM
有一个比以上答案更容易的方法!
NSDate *date = ... // The date you wish to test NSCalendar *calendar = [NSCalendar currentCalendar]; if([calendar isDateInToday:date]) { //do stuff }
对于iOS7和更早版本:
//this is now => need that for the current date NSDate * now = [NSDate date]; NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; [calendar setTimeZone:[NSTimeZone systemTimeZone]]; NSDateComponents * components = [calendar components:( NSYearCalendarUnit| NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit) fromDate: now]; [components setMinute:0]; [components setHour:0]; [components setSecond:0]; //this is Today's Midnight NSDate *todaysMidnight = [calendar dateFromComponents: components]; //now timeIntervals since Midnight => in seconds NSTimeInterval todayTimeInterval = [now timeIntervalSinceDate: todaysMidnight]; //now timeIntervals since OtherDate => in seconds NSTimeInterval otherDateTimeInterval = [now timeIntervalSinceDate: otherDate]; if(otherDateTimeInterval > todayTimeInterval) //otherDate is not in today { if((otherDateTimeInterval - todayTimeInterval) <= 86400) //86400 == a day total seconds { @"yesterday"; } else { @"earlier"; } } else { @"today"; } now = nil; calendar = nil; components = nil; todaysMidnight = nil; NSLog("Thank you :-)");
这可能会重新作为一个NSDate类别,但我用:
// Seconds per day (24h * 60m * 60s) #define kSecondsPerDay 86400.0f + (BOOL) dateIsToday:(NSDate*)dateToCheck { // Split today into components NSCalendar* gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSDateComponents* comps = [gregorian components:(NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit|NSHourCalendarUnit|NSMinuteCalendarUnit|NSSecondCalendarUnit) fromDate:[NSDate date]]; // Set to this morning 00:00:00 [comps setHour:0]; [comps setMinute:0]; [comps setSecond:0]; NSDate* theMidnightHour = [gregorian dateFromComponents:comps]; [gregorian release]; // Get time difference (in seconds) between date and then NSTimeInterval diff = [dateToCheck timeIntervalSinceDate:theMidnightHour]; return ( diff>=0.0f && diff<kSecondsPerDay ); }
(然而,比较原来问题中的两个datestring几乎感觉“更清洁”..)
检查我们的Erica Sadun的伟大的NSDate extension
。 使用非常简单。 在这里罚款:
http://github.com/erica/NSDate-Extensions
它已经在这篇文章中: https : //stackoverflow.com/a/4052798/362310
正确和安全的解决scheme,不用强制解包,在Swift 2.2和iOS 8之前工作:
func isToday() -> Bool { let calendar = NSCalendar.currentCalendar() if #available(iOS 8.0, *) { return calendar.isDateInToday(self) } let todayComponents = calendar.components([.Era, .Year, .Month, .Day], fromDate:NSDate()) let dayComponents = calendar.components([.Era, .Year, .Month, .Day], fromDate:self) guard let today = calendar.dateFromComponents(todayComponents), day = calendar.dateFromComponents(dayComponents) else { return false } return today.compare(day) == .OrderedSame }
这是我接受的答案build立在2分的答案,但也支持更新的API。 注:我使用公历作为大多数时间戳是格林尼治标准时间,但改变你的看法
func isDateToday(date: NSDate) -> Bool { let calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)! if calendar.respondsToSelector("isDateInToday:") { return calendar.isDateInToday(date) } let dateComponents = NSCalendarUnit.CalendarUnitYear | NSCalendarUnit.CalendarUnitMonth | NSCalendarUnit.CalendarUnitDay let today = calendar.dateFromComponents(calendar.components(dateComponents, fromDate: NSDate()))! let dateToCompare = calendar.dateFromComponents(calendar.components(dateComponents, fromDate: date))! return dateToCompare == today }
我的解决scheme是计算自1970年以来通过划分多less天,比较整数部分
#define kOneDay (60*60*24) - (BOOL)isToday { NSInteger offset = [[NSTimeZone defaultTimeZone] secondsFromGMT]; NSInteger days =[self timeIntervalSince1970] + offset; NSInteger currentDays = [[NSDate date] timeIntervalSince1970] + offset; return (days / kOneDay == currentDays / kOneDay); }
NSDate *dateOne = yourDate; NSDate *dateTwo = [NSDate date]; switch ([dateOne compare:dateTwo]) { case NSOrderedAscending: NSLog(@”NSOrderedAscending”); break; case NSOrderedSame: NSLog(@”NSOrderedSame”); break; case NSOrderedDescending: NSLog(@”NSOrderedDescending”); break; }