【问题标题】:How to compare two NSDates: Which is more recent?如何比较两个 NSDate:哪个是最近的?
【发布时间】:2011-08-23 07:55:32
【问题描述】:

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

我想出了以下方法,但得到了意想不到的结果。我想在比较这两个日期时我做错了什么。我只是使用了 >

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.

【问题讨论】:

  • 重复:123456&c.
  • @JoshCaswell 如果它是一个真正的副本,为什么不合并它们呢?你以前做过……
  • 只有钻石版主才能执行合并,@Yar。

标签: iphone objective-c cocoa-touch nsdate


【解决方案1】:

假设有两个日期:

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

【讨论】:

  • 可爱! Beats 搞砸 [date1 earlyDate:date2] 等...谢谢 - 出于某种原因,我从没想过使用 compare: before。
  • 我喜欢依赖 NSOrderedAscending 0 的事实。这使得比较更容易阅读:[date1 compare:date2]
  • 嗯 - 比较方法与逐个错误一样容易出错。因此,您应该使用 (NSDate *)laterDate:(NSDate *)anotherDate 这将返回两者的较晚日期。所以你只需比较你的预期结果,你就完成了!不用摆弄“Waaait 下降/上升?!”
  • @jpap 这也把我搞砸了;似乎 Apple 希望您将结果视为 date1 -&gt; date2 升序/降序(因此 date1 分别更晚或更早)。
  • 这是我今天发现的一个严重问题,如果你比较两个相同的日期但不同的时间结果会有所不同,例如如果我比较今天的日期'2017-03-27 14: 26:38 +0000' 与 NSOrderedDescending 的 '2017-03-27 10:16:14 +0000' 结果将为 TRUE,而如果我比较今天的日期 '2017-03-27 00:00:01 +0000 ' 与 '2017-03-27 10:07:29 +0000' 结果将为 FALSE。并不是说答案是错误的,但对于只想比较日期的人来说,不应该使用它。
【解决方案2】:

迟到了,但是比较 NSDate 对象的另一种简单方法是将它们转换为基本类型,这样可以轻松使用 '>' '

例如。

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

timeIntervalSinceReferenceDate 将日期转换为自参考日期(2001 年 1 月 1 日,格林威治标准时间)以来的秒数。由于timeIntervalSinceReferenceDate 返回一个 NSTimeInterval(它是一个 double typedef),我们可以使用原始比较器。

【讨论】:

  • (NSComparisonResult)compare:(NSDate *) 稍微直观一点,但对于这个简单的操作来说仍然相当冗长......(和往常一样)
  • 也可以[dateA timeIntervalSinceDate:dateB] &gt; 0
【解决方案3】:

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

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

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

然后,您可以直接将 NSDates 与 &lt;&gt;==(已支持)进行比较。

【讨论】:

  • 如果我尝试对此进行扩展,我会得到“只允许在全局范围内使用运算符”,建议?
  • @JohnVanDijk 你不能把它放在扩展中。我会将它与扩展名放在同一个文件中,但在 { ... } 之外
【解决方案4】:

NSDate 有比较功能。

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

(NSComparisonResult)compare:(NSDate *)anotherDate

参数anotherDate 与接收者进行比较的日期。 该值不能为零。如果值为 nil,则行为未定义,并且可能会在 Mac OS X 的未来版本中发生变化。

返回值:

  • 如果receiver和anotherDate完全相等,NSOrderedSame
  • 如果接收者的时间晚于另一个日期,NSOrderedDescending
  • 如果接收者在时间上早于另一个日期,NSOrderedAscending

【讨论】:

  • @Irene 有没有办法比较两个只有时间分量不同的 NSDate 对象?由于某种原因,上述方法不起作用。
【解决方案5】:

您想使用 NSDate compare:、laterDate:、earlierDate: 或 isEqualToDate: 方法。在这种情况下使用 运算符是比较指针,而不是日期

【讨论】:

    【解决方案6】:
    - (NSDate *)earlierDate:(NSDate *)anotherDate
    

    这将返回接收者和另一个日期中的较早者。如果两者相同,则返回接收者。

    【讨论】:

    • 请注意,NSDates 的支持对象可能会在您编译的代码的 64 位版本上进行优化,以便表示相同时间的日期将具有相同的地址。因此,如果cDate = [aDate earlierDate:bDate]cDate == aDatecDate == bDate 都可以为真。发现这在 iOS 8 上做一些约会工作。
    • 相反,在 32 位平台上,如果日期不同,-earlierDate:(和-laterDate:)既不能返回接收者,也不能返回参数。
    • 实际上 - 我之前关于 32 位平台的评论是不正确的。 -earlierDate:-laterDate: 返回参数或接收器。但是,NSManagedObjects 上的 NSDate 属性将为每次调用返回不同的实例。
    【解决方案7】:

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

    #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
    

    【讨论】:

    【解决方案8】:

    你应该使用:

    - (NSComparisonResult)compare:(NSDate *)anotherDate
    

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

    【讨论】:

      【解决方案9】:

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

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

      【讨论】:

        【解决方案10】:

        我遇到了几乎相同的情况,但就我而言,我正在检查天数是否存在差异

        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 时很有用

        【讨论】:

        • NSDayCalendarUnit 已弃用,因此请改用 NSCalendarUnitDay
        【解决方案11】:

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

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

        【讨论】:

          【解决方案12】:

          我试过了,希望对你有用

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

          【讨论】:

            【解决方案13】:

            使用这个简单的函数进行日期比较

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2011-07-09
              • 2012-04-11
              • 1970-01-01
              • 1970-01-01
              • 2012-05-07
              • 1970-01-01
              • 2012-05-30
              • 2021-10-20
              相关资源
              最近更新 更多