【问题标题】:2 NSDates that should be equal aren't?2个应该相等的NSDates不是吗?
【发布时间】:2011-04-28 18:46:23
【问题描述】:

我正在使用来自 Stig Brautaset (http://code.google.com/p/json-framework) 的 JSON 库,我需要序列化一个 NSDate。我正在考虑在 JSON 化之前将其转换为字符串,但是,我遇到了这种奇怪的行为:

为什么这些 NSDate 不相等?

NSDate *d = [[NSDate alloc] init];
NSDate *dd = [NSDate dateWithString:[d description]];

NSLog(@"%@", d);
NSLog(@"%@", dd);
if( [d isEqualToDate:dd] ){
    NSLog(@"Yay!");
}

【问题讨论】:

    标签: objective-c cocoa nsdate equality


    【解决方案1】:

    当您描述原始日期对象时,您会失去原始对象的亚秒精度——换句话说,-description 会减少小数秒,然后返回

    以国际格式YYYY-MM-DD HH:MM:SS ±HHMM 表示的接收方字符串,其中±HHMM 表示与GMT 的时区偏移(以小时和分钟为单位)

    当你根据描述创建一个新的日期对象时,你会在整秒内得到它,因为字符串只精确到整秒。所以-isEqualToDate: 返回NO,因为你的两个日期对象之间存在几分之一秒的差异,这是敏感的。

    此方法检测日期之间的亚秒级差异。如果您想比较粒度较小的日期,请使用timeIntervalSinceDate: 比较两个日期。

    所以你应该这样做(NSTimeInterval 以秒为单位):

    if ([d timeIntervalSinceDate:dd] == 0) {
        NSLog(@"Yay!");
    }
    

    【讨论】:

    • 当我的两个日期显然相隔 0.0005 秒时,-timeIntervalSinceDate: 返回非零。我最终比较了每个日期的[NSString stringWithFormat:@"%.3f", d]
    • NSDate.timeIntervalSinceDate 返回一个 NSTimeInterval,它是一个 Double 值,它可能小于一秒。在这种情况下,我建议像这样检查 `[d timeIntervalSinceDate:dd]
    【解决方案2】:

    isEqualToDate 检测日期之间的亚秒差异,但描述方法不包括亚秒。

    【讨论】:

      【解决方案3】:

      因为它们不等价:

      NSDate *d = [NSDate date];
      NSDate *dd = [NSDate dateWithString:[d description]];
      NSLog(@"%f", [d timeIntervalSinceReferenceDate]);
      NSLog(@"%f", [dd timeIntervalSinceReferenceDate]);
      

      生产:

      2011-04-28 11:58:11.873 EmptyFoundation[508:903] 325709891.867788
      2011-04-28 11:58:11.874 EmptyFoundation[508:903] 325709891.000000
      

      换句话说,+dateWithString: 方法不能保持亚秒级精度。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-12
        • 1970-01-01
        • 1970-01-01
        • 2017-12-06
        • 2021-03-16
        相关资源
        最近更新 更多