我需要知道两个NSDate实例是否都来自同一天 .
有没有比获得NSDateComponents和比较日/月/年更容易/更好的方法呢?
在Swift中:
NSCalendar.currentCalendar().isDate(yourDate, equalToDate: yourOtherDate, toUnitGranularity: .Day)
如果它们在同一天,它将返回true .
NSDateComponents听起来对我来说是最好的选择 . 另一种尝试的策略是免费将其桥接到CFDate,然后使用CFDateGetAbsoluteTime并进行减法以获得两个日期之间的时间量 . 然而,你必须做一些额外的数学计算,以确定时差是否在同一天登陆日期 .
如果你的目标是 iOS 8 (and OS X 10.9) or later ,那么Joe's answer是一个更好的解决方案,使用NSCalendar中的新方法就是为了这个目的:
-[NSCalendar isDate:inSameDayAsDate:]
For iOS 7 or earlier :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: .
-isDate:inSameDayAsDate:
来自 NSCalendar.h :
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);
请注意,由于某些原因,这不适用于Apple开发者网站上的官方文档 . 但它肯定是公共API的一部分 .
(注意:看看Joe的答案是否能在iOS 8上做到这一点)
我只使用日期格式化程序:
NSDateFormatter *dateComparisonFormatter = [[[NSDateFormatter alloc] init] autorelease]; [dateComparisonFormatter setDateFormat:@"yyyy-MM-dd"]; if( [[dateComparisonFormatter stringFromDate:firstDate] isEqualToString:[dateComparisonFormatter stringFromDate:secondDate]] ) { … }
HTH .
我喜欢progrmr的解决方案,但我会更进一步,制作一个提供此方法的 NSDate 类别 . 它将使您的代码稍微更具可读性,并且您不需要将该方法复制并粘贴到可能需要它的每个新类中 - 只需导入头文件即可 .
NSDate
@interface NSDate (SameDay) - (BOOL)isSameDayAsDate:(NSDate*)otherDate; @end
#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 之后,您可以像这样使用它:
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及更高版本 .
是的,有一种更简单的方法
-[NSCalendar rangeForUnit:startDate:interval:forDate:] 此方法可以轻松地将日期设置为单位的开头(日,小时,月,年......)并获取该单位的长度(间隔) .
-[NSCalendar rangeForUnit:startDate:interval:forDate:]
作为一个类别,它可能会被用作
@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) { }
我创建自己的实用程序类 .
@interface ZYUtility : NSObject + (NSDate *)yesterday; + (NSDate *)tomorrow; + (NSDate *)endOfDay:(NSDate *)date; + (NSDate *)beginningOfDay:(NSDate *)date; @end
+ (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; }
以下将测试两个日期是否代表给定时代的同一天(在许多情况下这是足够的):
- (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; }
12 回答
在Swift中:
如果它们在同一天,它将返回true .
NSDateComponents听起来对我来说是最好的选择 . 另一种尝试的策略是免费将其桥接到CFDate,然后使用CFDateGetAbsoluteTime并进行减法以获得两个日期之间的时间量 . 然而,你必须做一些额外的数学计算,以确定时差是否在同一天登陆日期 .
如果你的目标是 iOS 8 (and OS X 10.9) or later ,那么Joe's answer是一个更好的解决方案,使用NSCalendar中的新方法就是为了这个目的:
For iOS 7 or earlier :NSDateComponents是我的偏好 . 这样的事情怎么样:
如果您使用的是iOS 8,则可以使用
-isDate:inSameDayAsDate:
.来自
NSCalendar.h
:请注意,由于某些原因,这不适用于Apple开发者网站上的官方文档 . 但它肯定是公共API的一部分 .
(注意:看看Joe的答案是否能在iOS 8上做到这一点)
我只使用日期格式化程序:
HTH .
我喜欢progrmr的解决方案,但我会更进一步,制作一个提供此方法的
NSDate
类别 . 它将使您的代码稍微更具可读性,并且您不需要将该方法复制并粘贴到可能需要它的每个新类中 - 只需导入头文件即可 .NSDate SameDay.h
NSDate SameDay.m
然后,在您的类中导入
NSDate+SameDay.h
之后,您可以像这样使用它:我使用NSDateComponents去除时间方面然后进行比较 . 就像是:
适用于iOS 8.0及更高版本以及OS X v10.9及更高版本 .
是的,有一种更简单的方法
-[NSCalendar rangeForUnit:startDate:interval:forDate:]
此方法可以轻松地将日期设置为单位的开头(日,小时,月,年......)并获取该单位的长度(间隔) .作为一个类别,它可能会被用作
此类别适用于所有iOS版本和Mac OS X 10.5 .
对于iOS 8和Mac OS X 10.9,您可以使用NSCalendars
在Swift 3.0,iOS8中
要么
我创建自己的实用程序类 .
ZYUtility.h
ZYUtility.m
以下将测试两个日期是否代表给定时代的同一天(在许多情况下这是足够的):