Cocoa-Touch:我如何看待两个NSD在同一天?

时间:2009-10-13 16:59:12

标签: ios objective-c macos cocoa-touch

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

是否有更容易/更好的方法来获取NSDateComponents并比较日/月/年?

12 个答案:

答案 0 :(得分:154)

如果您的目标是 iOS 8(和OS X 10.9)或更高版本,那么Joe's answer是使用NSCalendar中的新方法的更好解决方案,仅用于此目的:

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

答案 1 :(得分:53)

如果您使用的是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);

请注意,由于某些原因,这不适用于Apple开发者网站上的官方文档。但它绝对是公共API的一部分。

答案 2 :(得分:24)

(注意:看看Joe在iOS 8 +上做到这一点的好方法的答案)

我只使用日期格式化程序:

NSDateFormatter *dateComparisonFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateComparisonFormatter setDateFormat:@"yyyy-MM-dd"];

if( [[dateComparisonFormatter stringFromDate:firstDate] isEqualToString:[dateComparisonFormatter stringFromDate:secondDate]] ) {
    …
}

HTH。

答案 3 :(得分:13)

在斯威夫特:

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

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

答案 4 :(得分:11)

我喜欢progrmr的解决方案,但我会更进一步,制作一个提供此方法的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...
}

答案 5 :(得分:7)

NSDateComponents听起来对我来说是最好的选择。另一种尝试的策略是免费将其桥接到CFDate,然后使用CFDateGetAbsoluteTime并进行减法以获得两个日期之间的时间量。然而,你必须做一些额外的数学计算,以确定时差是否在同一天登陆日期。

答案 6 :(得分:5)

我使用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];
}

答案 7 :(得分:4)

u

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

答案 8 :(得分:1)

  

是否有更容易/更好的方法来获取NSDateComponents并比较日/月/年?

是的,有一种更简单的方式

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

答案 9 :(得分:1)

在Swift 3.0,iOS8 +

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

}

if NSCalendar.current.isDateInToday(date) {

}

答案 10 :(得分:-1)

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

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

答案 11 :(得分:-1)

以下将测试两个日期是否代表特定时代的同一天(在许多情况下这是足够的):

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