iOS:比较两个日期

97

我有一个NSDate需要与另外两个NSDate进行比较,我尝试使用NSOrderAscendingNSOrderDescending,但如果我的日期等于其他两个日期呢?

例如,如果我有一个myDate = 2011年5月24日,还有另外两个日期分别为一个2011年5月24日和二2011年5月24日,我应该使用什么?


1
我不完全理解你的问题,你想要实现什么? - arclight
日期一和日期二可以是: 一 = 2011年5月15日 二 = 2011年5月31日 但它们必须是同一天 一 = 2011年5月24日 二 = 2011年5月24日 然后我必须检查myData是否在日期一和日期二之间。 - cyclingIsBetter
只需提取年、月和日期,然后按顺序进行比较。如果有平局,则比较下一个字段。 - Himadri Choudhury
6个回答

210

根据苹果公司对NSDate compare:的文档说明

返回一个NSComparisonResult值,该值指示接收器和另一个给定日期的时间顺序。

- (NSComparisonResult)compare:(NSDate *)anotherDate

参数 anotherDate

要与接收器进行比较的日期。此值不能为nil。 如果该值为nil,则行为未定义,并且可能会在将来的Mac OS X版本中更改。

返回值

如果:

接收器和anotherDate完全相等, NSOrderedSame

接收器比anotherDate晚, NSOrderedDescending

接收器比anotherDate早, NSOrderedAscending

换句话说:

if ([date1 compare:date2] == NSOrderedSame) ...

请注意,在您的特定情况下,阅读和编写可能更容易:

if ([date2 isEqualToDate:date2]) ...

请看苹果文档


但是如果 f([date1 compare:date2]==NSOrderedSame)还要检查小时、分钟和秒,我不想。 - cyclingIsBetter
1
你的问题有点不清楚,抱歉,请看一下https://dev59.com/dHI-5IYBdhLWcg3wYXL8,你会找到答案的。 - Vincent Guerci
这个答案两种方式都是正确的。要控制你正在比较的日期组件,请使用 NSDateComponents - Nazir

33

经过搜索,我得出结论,最好的方法是像这样:

- (BOOL)isEndDateIsSmallerThanCurrent:(NSDate *)checkEndDate
{
    NSDate* enddate = checkEndDate;
    NSDate* currentdate = [NSDate date];
    NSTimeInterval distanceBetweenDates = [enddate timeIntervalSinceDate:currentdate];
    double secondsInMinute = 60;
    NSInteger secondsBetweenDates = distanceBetweenDates / secondsInMinute;

    if (secondsBetweenDates == 0)
        return YES;
    else if (secondsBetweenDates < 0)
        return YES;
    else
        return NO;
}

你也可以将其更改为小时之间的差异。


如果你只想比较日期格式为 dd/MM/yyyy 的日期,那么你需要在 NSDate* currentdate = [NSDate date];NSTimeInterval distance 之间添加以下行:

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"dd/MM/yyyy"];
[dateFormatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]
                          autorelease]];

NSString *stringDate = [dateFormatter stringFromDate:[NSDate date]];

currentdate = [dateFormatter dateFromString:stringDate];

1
谢谢,这比compare或isEqualToDate更好用。 - ArdenDev
同意。我发现使用compare和isEqualToDate存在问题。当然,这可能需要额外的两行代码,但更可靠。 - Coach Roebuck

23

我理解您在询问比较函数中的返回值。

如果日期相等,则返回NSOrderedSame

如果升序(第二个参数大于第一个参数),则返回NSOrderedAscending

如果降序(第二个参数小于第一个参数),则返回NSOrderedDescending


升序和降序的好思考方式。 - David

16

我不确定你是否已经提出了这个问题,但如果你只想比较NSDate的日期部分,你需要使用NSCalendar和NSDateComponents来去除时间部分。

类似以下代码应该能够作为NSDate的一个类别:

- (NSComparisonResult)compareDateOnly:(NSDate *)otherDate {
    NSUInteger dateFlags = NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit;
    NSCalendar *gregorianCalendar = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
    NSDateComponents *selfComponents = [gregorianCalendar components:dateFlags fromDate:self];
    NSDate *selfDateOnly = [gregorianCalendar dateFromComponents:selfComponents];

    NSDateComponents *otherCompents = [gregorianCalendar components:dateFlags fromDate:otherDate];
    NSDate *otherDateOnly = [gregorianCalendar dateFromComponents:otherCompents];
    return [selfDateOnly compare:otherDateOnly];
}

2

NSDate 实际上表示自参考日期(我想是2000年1月1日UTC)以来的秒数时间间隔。内部使用双精度浮点数,因此即使在同一天,两个任意日期也极不可能相等。如果您想查看特定日期是否落在特定日期,可能需要使用 NSDateComponents。例如:

NSDateComponents* dateComponents = [[NSDateComponents alloc] init];
[dateComponents setYear: 2011];
[dateComponents setMonth: 5];
[dateComponents setDay: 24];
/*
 *  Construct two dates that bracket the day you are checking.  
 *  Use the user's current calendar.  I think this takes care of things like daylight saving time.
 */
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDate* startOfDate = [calendar dateFromComponents: dateComponents];
NSDateComponents* oneDay = [[NSDateComponents alloc] init];
[oneDay setDay: 1];
NSDate* endOfDate = [calendar dateByAddingComponents: oneDay toDate: startOfDate options: 0];
/*
 *  Compare the date with the start of the day and the end of the day.
 */
NSComparisonResult startCompare = [startOfDate compare: myDate];
NSComparisonResult endCompare = [endOfDate compare: myDate];

if (startCompare != NSOrderedDescending && endCompare == NSOrderedDescending)
{
    // we are on the right date
} 

2

首先检查以下日期比较函数,首先创建两个NSDate对象并将其传递给函数: 在viewDidload中或根据您的情况添加以下代码行。

-(void)testDateComaparFunc{

NSString *getTokon_Time1 = @"2016-05-31 03:19:05 +0000";
NSString *getTokon_Time2 = @"2016-05-31 03:18:05 +0000";
NSDateFormatter *dateFormatter=[NSDateFormatter new];
[dateFormatter setDateFormat:@"yyyy-MM-dd hh:mm:ss Z"];
NSDate *tokonExpireDate1=[dateFormatter dateFromString:getTokon_Time1];
NSDate *tokonExpireDate2=[dateFormatter dateFromString:getTokon_Time2];
BOOL isTokonValid = [self dateComparision:tokonExpireDate1 andDate2:tokonExpireDate2];}

这是函数:
-(BOOL)dateComparision:(NSDate*)date1 andDate2:(NSDate*)date2{

BOOL isTokonValid;

if ([date1 compare:date2] == NSOrderedDescending) {
    //"date1 is later than date2
    isTokonValid = YES;
} else if ([date1 compare:date2] == NSOrderedAscending) {
    //date1 is earlier than date2
    isTokonValid = NO;
} else {
   //dates are the same
    isTokonValid = NO;

}

return isTokonValid;}

只需更改日期并测试上述功能 :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接