比较两个NSDates并忽略时间组件

Mag*_*ave 71 iphone objective-c nsdate

比较两个NSDates的最有效/推荐方法是什么?我希望能够看到两个日期是否在同一天,无论时间如何,并且已经开始编写一些在NSDate类中使用timeIntervalSinceDate:方法的代码,并获取此值的整数除以秒数一天内.这似乎很长,我觉得我错过了一些明显的东西.

我试图解决的代码是:

if (!([key compare:todaysDate] == NSOrderedDescending))
{
    todaysDateSection = [eventSectionsArray count] - 1;
}
Run Code Online (Sandbox Code Playgroud)

其中key和todaysDate是NSDate对象,todaysDate正在使用:

NSDate *todaysDate = [[NSDate alloc] init];
Run Code Online (Sandbox Code Playgroud)

问候

戴夫

Ed *_*rty 83

我很惊讶没有其他答案有这个选项来获取对象的"开始日期"日期:

[[NSCalendar currentCalendar] rangeOfUnit:NSCalendarUnitDay startDate:&date1 interval:NULL forDate:date1];
[[NSCalendar currentCalendar] rangeOfUnit:NSCalendarUnitDay startDate:&date2 interval:NULL forDate:date2];
Run Code Online (Sandbox Code Playgroud)

其中规定date1date2各自的日子的开始.如果他们是平等的,他们就在同一天.

或者这个选项:

NSUInteger day1 = [[NSCalendar currentCalendar] ordinalityOfUnit:NSDayCalendarUnit inUnit: forDate:date1];
NSUInteger day2 = [[NSCalendar currentCalendar] ordinalityOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitEra forDate:date2];
Run Code Online (Sandbox Code Playgroud)

哪些设置day1day2可以比较的某些任意值.如果他们是平等的,他们就在同一天.

  • +1我之前从未注意过这些方法!很酷. (2认同)

Gre*_*osz 72

在进行比较之前,您将日期中的时间设置为00:00:00:

unsigned int flags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay;
NSCalendar* calendar = [NSCalendar currentCalendar];

NSDateComponents* components = [calendar components:flags fromDate:date];

NSDate* dateOnly = [calendar dateFromComponents:components];

// ... necessary cleanup
Run Code Online (Sandbox Code Playgroud)

然后您可以比较日期值.请参阅参考文档中概述.

  • 我的建议是:正确实施是黄金; 然后简介.如果这个特定的循环确实是一个瓶颈,那么优化 (13认同)
  • 由于您只提取年,月和日单位,小时,分钟和秒自动设置为0.因此,您不必自己明确地执行此操作. (3认同)

sta*_*886 19

有一个新的方法被引入到NSCalendar与iOS 8,使这更容易.

- (NSComparisonResult)compareDate:(NSDate *)date1 toDate:(NSDate *)date2 toUnitGranularity:(NSCalendarUnit)unit NS_AVAILABLE(10_9, 8_0);
Run Code Online (Sandbox Code Playgroud)

您将粒度设置为重要的单位.这忽略了所有其他单位并限制与所选单位的比较.


Jam*_*mes 14

对于iOS8及更高版本,检查同一天是否出现两个日期非常简单:

[[NSCalendar currentCalendar] isDate:date1 inSameDayAsDate:date2]
Run Code Online (Sandbox Code Playgroud)

文档


Bms*_*270 10

这是所有答案的简写:

NSInteger interval = [[[NSCalendar currentCalendar] components: NSDayCalendarUnit
                                                                  fromDate: date1
                                                                    toDate: date2
                                                                   options: 0] day];
    if(interval<0){
       //date1<date2
    }else if (interval>0){
       //date2<date1
    }else{
       //date1=date2
    }
Run Code Online (Sandbox Code Playgroud)


Fel*_*xyz 6

我用这个小的util方法:

-(NSDate*)normalizedDateWithDate:(NSDate*)date
{
   NSDateComponents* components = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit)
                                              fromDate: date];
   return [calendar_ dateFromComponents:components]; // NB calendar_ must be initialized
}
Run Code Online (Sandbox Code Playgroud)

(你显然需要一个叫做calendar_含有的伊娃NSCalendar.)

使用它,很容易检查今天的日期是这样的:

[[self normalizeDate:aDate] isEqualToDate:[self normalizeDate:[NSDate date]]];
Run Code Online (Sandbox Code Playgroud)

([NSDate date]返回当前日期和时间.)

这当然与格雷戈里的建议非常相似.这种方法的缺点是它往往会产生大量的临时NSDate对象.如果你要处理很多日期,我建议使用其他一些方法,比如直接比较组件,或者用NSDateComponents对象代替NSDates.


jce*_*ile 6

我使用了Duncan C的方法,我修正了他犯的一些错误

-(NSInteger) daysBetweenDate:(NSDate *)firstDate andDate:(NSDate *)secondDate { 

    NSCalendar *currentCalendar = [NSCalendar currentCalendar];
    NSDateComponents *components = [currentCalendar components: NSDayCalendarUnit fromDate: firstDate toDate: secondDate options: 0];

    NSInteger days = [components day];

    return days;
}
Run Code Online (Sandbox Code Playgroud)