如何比较两个NSDates:哪个更近?

时间:2011-05-11 13:27:46

标签: iphone objective-c cocoa-touch nsdate

我正在尝试实现dropBox同步,需要比较两个文件的日期。一个在我的dropBox帐户上,一个在我的iPhone上。

我想出了以下内容,但我得到了意想不到的结果。我想在比较这两个日期时我做了一些根本错误的事情。我只是用了> <运算符,但我想这并不好,因为我正在比较两个NSDate字符串。我们走了:

NSLog(@"dB...lastModified: %@", dbObject.lastModifiedDate); 
NSLog(@"iP...lastModified: %@", [self getDateOfLocalFile:@"NoteBook.txt"]);

if ([dbObject lastModifiedDate] < [self getDateOfLocalFile:@"NoteBook.txt"]) {
    NSLog(@"...db is more up-to-date. Download in progress...");
    [self DBdownload:@"NoteBook.txt"];
    NSLog(@"Download complete.");
} else {
    NSLog(@"...iP is more up-to-date. Upload in progress...");
    [self DBupload:@"NoteBook.txt"];
    NSLog(@"Upload complete.");
}

这给了我以下(随机和错误)输出:

2011-05-11 14:20:54.413 NotePage[6918:207] dB...lastModified: 2011-05-11 13:18:25 +0000
2011-05-11 14:20:54.414 NotePage[6918:207] iP...lastModified: 2011-05-11 13:20:48 +0000
2011-05-11 14:20:54.415 NotePage[6918:207] ...db is more up-to-date.

或者这个恰好是正确的:

2011-05-11 14:20:25.097 NotePage[6903:207] dB...lastModified: 2011-05-11 13:18:25 +0000
2011-05-11 14:20:25.098 NotePage[6903:207] iP...lastModified: 2011-05-11 13:19:45 +0000
2011-05-11 14:20:25.099 NotePage[6903:207] ...iP is more up-to-date.

13 个答案:

答案 0 :(得分:645)

我们假设两个日期:

NSDate *date1;
NSDate *date2;

然后,下面的比较将告诉哪个更早/更晚/相同:

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

有关详细信息,请参阅NSDate class documentation

答案 1 :(得分:47)

晚会,但另一种比较NSDate对象的简单方法是将它们转换为原始类型,以便于使用'&gt;' '&LT;' '=='等

例如

if ([dateA timeIntervalSinceReferenceDate] > [dateB timeIntervalSinceReferenceDate]) {
    //do stuff
}

timeIntervalSinceReferenceDate将日期转换为自参考日期(2001年1月1日,GMT)以来的秒数。当timeIntervalSinceReferenceDate返回NSTimeInterval(这是一个double typedef)时,我们可以使用原始比较器。

答案 2 :(得分:14)

在Swift中,您可以重载现有的运算符:

func > (lhs: NSDate, rhs: NSDate) -> Bool {
    return lhs.timeIntervalSinceReferenceDate > rhs.timeIntervalSinceReferenceDate
}

func < (lhs: NSDate, rhs: NSDate) -> Bool {
    return lhs.timeIntervalSinceReferenceDate < rhs.timeIntervalSinceReferenceDate
}

然后,您可以直接将NSDates与<>==(已经支持)进行比较。

答案 3 :(得分:13)

NSDate有比较功能。

compare:返回NSComparisonResult值,表示接收方的时间顺序和另一个给定日期。

(NSComparisonResult)compare:(NSDate *)anotherDate

参数anotherDate 比较接收器的日期。 该值不得为零。如果值为nil,则行为未定义,并且可能在将来的Mac OS X版本中更改。

返回值

  • 如果接收者和另一个日期彼此完全相同,NSOrderedSame
  • 如果接收者的时间晚于anotherDate,NSOrderedDescending
  • 如果接收者的时间早于anotherDate NSOrderedAscending

答案 4 :(得分:12)

您想使用NSDate compare:,laterDate:,earlyDate:或isEqualToDate:methods。使用&lt;和&gt;这种情况下的运算符是比较指针,而不是日期

答案 5 :(得分:11)

- (NSDate *)earlierDate:(NSDate *)anotherDate

这将返回接收器和anotherDate的早期版本。如果两者相同,则返回接收者。

答案 6 :(得分:7)

一些日期实用程序,包括比较IN ENGLISH,这很好:

#import <Foundation/Foundation.h>


@interface NSDate (Util)

-(BOOL) isLaterThanOrEqualTo:(NSDate*)date;
-(BOOL) isEarlierThanOrEqualTo:(NSDate*)date;
-(BOOL) isLaterThan:(NSDate*)date;
-(BOOL) isEarlierThan:(NSDate*)date;
- (NSDate*) dateByAddingDays:(int)days;

@end

实施:

#import "NSDate+Util.h"


@implementation NSDate (Util)

-(BOOL) isLaterThanOrEqualTo:(NSDate*)date {
    return !([self compare:date] == NSOrderedAscending);
}

-(BOOL) isEarlierThanOrEqualTo:(NSDate*)date {
    return !([self compare:date] == NSOrderedDescending);
}
-(BOOL) isLaterThan:(NSDate*)date {
    return ([self compare:date] == NSOrderedDescending);

}
-(BOOL) isEarlierThan:(NSDate*)date {
    return ([self compare:date] == NSOrderedAscending);
}

- (NSDate *) dateByAddingDays:(int)days {
    NSDate *retVal;
    NSDateComponents *components = [[NSDateComponents alloc] init];
    [components setDay:days];

    NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    retVal = [gregorian dateByAddingComponents:components toDate:self options:0];
    return retVal;
}

@end

答案 7 :(得分:6)

您应该使用:

- (NSComparisonResult)compare:(NSDate *)anotherDate

比较日期。目标C中没有运算符重载。

答案 8 :(得分:5)

为什么你们不使用这些NSDate比较方法:

- (NSDate *)earlierDate:(NSDate *)anotherDate;
- (NSDate *)laterDate:(NSDate *)anotherDate;

答案 9 :(得分:4)

我遇到了几乎相同的情况,但在我的情况下,我正在检查天数差异

NSCalendar *cal = [NSCalendar currentCalendar];
NSDateComponents *compDate = [cal components:NSDayCalendarUnit fromDate:fDate toDate:tDate options:0];
int numbersOfDaysDiff = [compDate day]+1; // do what ever comparison logic with this int.

当你需要比较天/月/年单位的NSDate时很有用

答案 10 :(得分:1)

您也可以通过此方法比较两个日期

        switch ([currenttimestr  compare:endtimestr])
        {
            case NSOrderedAscending:

                // dateOne is earlier in time than dateTwo
                break;

            case NSOrderedSame:

                // The dates are the same
                break;
            case NSOrderedDescending:

                // dateOne is later in time than dateTwo


                break;

        }

答案 11 :(得分:0)

我试过希望它适合你

NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];      
int unitFlags =NSDayCalendarUnit;      
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];     
NSDate *myDate; //= [[NSDate alloc] init];     
[dateFormatter setDateFormat:@"dd-MM-yyyy"];   
myDate = [dateFormatter dateFromString:self.strPrevioisDate];     
NSDateComponents *comps = [gregorian components:unitFlags fromDate:myDate toDate:[NSDate date] options:0];   
NSInteger day=[comps day];

答案 12 :(得分:0)

使用此简单功能进行日期比较

-(BOOL)dateComparision:(NSDate*)date1 andDate2:(NSDate*)date2{

BOOL isTokonValid;

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

return isTokonValid;}