Cocoa-Touch:如何查看两个NSDate是否在同一天?

我需要知道两个NSDate实例是否都是同一天。

有没有比获得NSDateComponents和比较日/月/年更容易/更好的方法呢?

NSDateComponents听起来像是我最好的select。 另一种策略是免费桥接到CFDate,然后使用CFDateGetAbsoluteTime并进行减法以获得两个date之间的时间量。 但是,你必须做一些额外的计算,以确定时间差是否在同一天登记date。

如果您的目标是iOS 8(和OS X 10.9)或更高版本 ,那么Joe的答案是在NSCalendar中使用新方法的一个更好的解决scheme,只是为了这个目的:

 -[NSCalendar isDate:inSameDayAsDate:] 

对于iOS 7或更早版本 :NSDateComponents是我的首选。 怎么样这样的事情:

 - (BOOL)isSameDayWithDate1:(NSDate*)date1 date2:(NSDate*)date2 { NSCalendar* calendar = [NSCalendar currentCalendar]; unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit; NSDateComponents* comp1 = [calendar components:unitFlags fromDate:date1]; NSDateComponents* comp2 = [calendar components:unitFlags fromDate:date2]; return [comp1 day] == [comp2 day] && [comp1 month] == [comp2 month] && [comp1 year] == [comp2 year]; } 

如果您正在使用iOS 8,则可以使用-isDate:inSameDayAsDate:

NSCalendar.h

 /* This API compares the Days of the given dates, reporting them equal if they are in the same Day. */ - (BOOL)isDate:(NSDate *)date1 inSameDayAsDate:(NSDate *)date2 NS_AVAILABLE(10_9, 8_0); 

请注意,由于某些原因,这并没有使其成为苹果开发者网站上的官方文档。 但它绝对是公共API的一部分。

(注意:请看Joe的回答,在iOS 8+上这样做的好方法)

我只是使用date格式化程序:

 NSDateFormatter *dateComparisonFormatter = [[[NSDateFormatter alloc] init] autorelease]; [dateComparisonFormatter setDateFormat:@"yyyy-MM-dd"]; if( [[dateComparisonFormatter stringFromDate:firstDate] isEqualToString:[dateComparisonFormatter stringFromDate:secondDate]] ) { … } 

HTH。

在Swift中:

 NSCalendar.currentCalendar().isDate(yourDate, equalToDate: yourOtherDate, toUnitGranularity: .Day) 

如果他们在同一天,它将返回true。

我喜欢progrmr的解决scheme,但我会走得更远,并提供这种方法的NSDate类别。 它会让你的代码更具可读性,而且你不需要将该方法复制并粘贴到每个可能需要它的新类中 – 只需导入头文件即可。

的NSDate + SameDay.h

 @interface NSDate (SameDay) - (BOOL)isSameDayAsDate:(NSDate*)otherDate; @end 

的NSDate + SameDay.m

 #import "NSDate+SameDay.h" @implementation NSDate (SameDay) - (BOOL)isSameDayAsDate:(NSDate*)otherDate { // From progrmr's answer... NSCalendar* calendar = [NSCalendar currentCalendar]; unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit; NSDateComponents* comp1 = [calendar components:unitFlags fromDate:self]; NSDateComponents* comp2 = [calendar components:unitFlags fromDate:otherDate]; return [comp1 day] == [comp2 day] && [comp1 month] == [comp2 month] && [comp1 year] == [comp2 year]; } @end 

然后,在你的类中导入NSDate+SameDay.h之后,你可以像这样使用它:

 if ([myFirstDate isSameDayAsDate:mySecondDate]) { // The two dates are on the same day... } 

我使用NSDateComponents去除时间方面,然后比较。 就像是:

 if ([[self beginningOfDay:date1] isEqualToDate:[self beginningOfDay:date2]]) { ... } - (NSDate *)beginningOfDay:(NSDate *)date { NSCalendar *calendar = [NSCalendar currentCalendar]; unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit; NSDateComponents *comp = [calendar components:unitFlags fromDate:date]; return [calendar dateFromComponents:comp]; } 
 NSCalendar.currentCalendar().isDateInToday(yourNSDate) 

适用于iOS 8.0及更高版本以及OS X v10.9及更高版本。

有没有比获得NSDateComponents和比较日/月/年更容易/更好的方法呢?

是的,有一个更简单的方法

-[NSCalendar rangeForUnit:startDate:interval:forDate:]这个方法可以很容易的将date设置为一个单位的开始(天,小时,月,年,…),并获得该单位的长度(间隔)。

作为一个类别,它可能会使用像

 @interface NSDate (Comparison) -(BOOL) isSameDay:(NSDate *)rhs; @end @implementation NSDate (Comparison) -(BOOL)isSameDay:(NSDate *)rhs { NSDate *lhs = self; NSDate *lhsStart; NSDate *rhsStart; NSCalendar *cal = [NSCalendar currentCalendar]; [cal rangeOfUnit:NSCalendarUnitDay startDate:&lhsStart interval:NULL forDate:lhs]; [cal rangeOfUnit:NSCalendarUnitDay startDate:&rhsStart interval:NULL forDate:rhs]; return [lhsStart compare:rhsStart] == NSOrderedSame; } @end 

此类别适用于所有iOS版本和Mac OS X 10.5+。

对于iOS 8+和Mac OS X 10.9+,您可以使用NSCalendars

 - (BOOL)isDate:(NSDate *)date1 equalToDate:(NSDate *)date2 toUnitGranularity:(NSCalendarUnit)unit; 

在Swift 3.0中,iOS8 +

 if NSCalendar.current.isDate(Date(), equalTo: date, toGranularity: .day) { } 

要么

 if NSCalendar.current.isDateInToday(date) { } 

我创build了我自己的实用程序类。

ZYUtility.h

 @interface ZYUtility : NSObject + (NSDate *)yesterday; + (NSDate *)tomorrow; + (NSDate *)endOfDay:(NSDate *)date; + (NSDate *)beginningOfDay:(NSDate *)date; @end 

ZYUtility.m

 + (NSDate *)yesterday; { NSCalendar *calendar = [NSCalendar currentCalendar]; NSDateComponents *componets = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:[NSDate date]]; componets.day -= 1; componets.hour = 24; componets.minute = 0; componets.second = 0; return [calendar dateFromComponents:componets]; } + (NSDate *)tomorrow; { NSCalendar *calendar = [NSCalendar currentCalendar]; NSDateComponents *componets = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:[NSDate date]]; componets.day += 1; componets.hour = 0; componets.minute = 0; componets.second = 0; return [calendar dateFromComponents:componets]; } + (NSDate *)beginningOfDay:(NSDate *)date { NSCalendar *calendar = [NSCalendar currentCalendar]; unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit; NSDateComponents *comp = [calendar components:unitFlags fromDate:date]; return [calendar dateFromComponents:comp]; } + (NSDate *)endOfDay:(NSDate *)date { NSCalendar *calendar = [NSCalendar currentCalendar]; NSDateComponents *components = [NSDateComponents new]; components.day = 1; NSDate *theDate = [calendar dateByAddingComponents:components toDate:[ZYUtility beginningOfDay:date] options:0]; theDate = [theDate dateByAddingTimeInterval:-1]; return theDate; } 

下面将testing两个date是否代表同一个时代的同一天(这在许多情况下是足够的):

 - (BOOL)isDate:(NSDate *)date1 sameDayAsDate:(NSDate *)date2 { NSCalendar *calendar = [NSCalendar currentCalendar]; int diff = [calendar ordinalityOfUnit:NSDayCalendarUnit inUnit:NSEraCalendarUnit forDate:date1] - [calendar ordinalityOfUnit:NSDayCalendarUnit inUnit:NSEraCalendarUnit forDate:date2]; return 0 == diff; }