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; }