【问题标题】:Parse ISO8601 date in Objective-C (iPhone OS SDK)在 Objective-C (iPhone OS SDK) 中解析 ISO8601 日期
【发布时间】:2010-05-09 02:31:30
【问题描述】:

如何将“2010-04-30T00:45:48.711127”解析为 NSDate? (并保持所有精度)

【问题讨论】:

  • hint FWIW:你的问题是模棱两可的——你是在问一个关于 Cocoa 的“初学者”问题(“我如何以给定格式解析日期”)还是一个高级问题,这并不是 100% 清楚一。在你的情况下,根据你的 cmets 答案,你问的是高级版本。既然如此,如果你在答案中加入一个注释,例如,你可能会得到更少的噪音。 “我知道 NSDateFormatter 可以用于这种格式,但它的精度太早用完了三个位置。”。

标签: objective-c nsdate iso8601


【解决方案1】:

你的工作已经完成了。

NSDate 将丢弃超过小数点后 3 位的任何值秒。您可以创建NSDate 的子类以保持该精度,但您还需要实现自己的解析和自定义格式化程序来输入和显示它,因为它建立在NSDateFormatterCFDateFormatter 之上,将还截断小数点后 3 位的精度。取决于你在做什么,虽然这不应该那么难。

这是一个简单的子类(未实现 NSCodingNSCopying),它将保持您给它的所有精度。

@interface RMPreciseDate : NSDate {
    double secondsFromAbsoluteTime;
}

@end

@implementation RMPreciseDate

- (NSTimeInterval)timeIntervalSinceReferenceDate {
    return secondsFromAbsoluteTime;
}

- (id)initWithTimeIntervalSinceReferenceDate:(NSTimeInterval)secsToBeAdded {
    if (!(self = [super init]))
        return nil;

    secondsFromAbsoluteTime = secsToBeAdded;

    return self;
}

@end

然后您可以要求-timeIntervalSince1970 获取 UNIX 纪元时间。

那里已经有一个ISO8601 date/time parser class,但是由于它使用NSDateComponents 来生成它的日期,它目前仅限于整秒精度,但您可以将它作为起点,或许可以创建更精确的表示。

【讨论】:

    【解决方案2】:

    我将在类似的情况下尝试这个 ISO 8601 解析器和反解析器:http://boredzo.org/iso8601parser/

    【讨论】:

      【解决方案3】:

      NSDate 似乎只有毫秒精度。

      #import <Foundation/Foundation.h>
      
      int main (int argc, const char * argv[]) {
          NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
      
          NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
          [dateFormatter setDateFormat:@"yyyy-MM-dd'T'hh:mm:ss.SSSSSS"];
      
          NSDate *date = [dateFormatter dateFromString:@"2010-04-30T00:45:48.711127"];
      
          NSLog(@"%@", date);
      
          NSString *string = [dateFormatter stringFromDate:date];
      
          NSLog(@"%@", string);
      
          [pool drain];
          return 0;
      }
      

      该代码产生以下控制台输出:

      Program loaded.
      run
      [Switching to process 27202]
      Running…
      2010-05-08 20:02:46.342 TestNSDate[27202:a0f] 2010-04-30 00:45:48 -0700
      2010-05-08 20:02:46.344 TestNSDate[27202:a0f] 2010-04-30T12:45:48.711000
      
      Debugger stopped.
      Program exited with status value:0.
      

      所以"2010-04-30T00:45:48.711127" 变成"2010-04-30T00:45:48.711000" 可能不是你想的那样。

      【讨论】:

      • 看来我们都被困在了同一点上。我认为问题出在 NSDateFormatter 上,因为在许多地方都记录了 NSDate 支持微秒精度。
      • NSTimeInterval 拥有这种能力。也许复合模式是有序的......
      • 也许我应该更具体一点:在 NSDate 本身中存储这些亚毫秒分辨率时间戳(为了获得更好的描述)有多重要?难道处理微秒分辨率的子类不能弥补您需要的额外精度的差异吗?
      • 您的代码有一个小错误。您应该将格式更改为 yyyy-MM-dd'T'HH:mm:ss.SSSSSS(注意 HH 而不是 hh),因为 iso fromat 中的时间使用 24 小时制而不是 12 小时制。
      猜你喜欢
      • 2012-07-30
      • 1970-01-01
      • 1970-01-01
      • 2018-01-12
      • 1970-01-01
      • 2012-10-28
      • 2012-01-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多