【问题标题】:iOS 6.1 NSDateFormatter has changed since iOS 5 - broken parsing?iOS 6.1 NSDateFormatter 自 iOS 5 以来发生了变化 - 解析失败?
【发布时间】:2013-01-24 07:53:36
【问题描述】:

我们的 iOS iPhone 应用包含这段代码,它在 iOS 5 中生成了一个名为 resultDate 的有效 NSDate 对象:

    static NSDateFormatter *invariantFmt = nil;
    if (!invariantFmt) {
        invariantFmt = [[NSDateFormatter alloc] init];
        NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
        [invariantFmt setLocale:locale];
        [locale release];
        [invariantFmt setDateStyle:NSDateFormatterShortStyle];
        [invariantFmt setTimeStyle:NSDateFormatterMediumStyle];
    }
    NSDate *resultDate = [invariantFmt dateFromString:@"08/04/2010 10:43:39 AM"];

升级到 XCode 4.6 和 iOS 6.1 后,该代码现在为 resultDate 提供 nil,因此它们用于解析的内容发生了变化。发行说明没有说明 NSDateFormatter 的变化。 Internet 研究表明,他们可能已更改为使用更新的 Unicode UTS 语言环境解析标准。显然他们改变了一些东西。在处理完代码并获取一个已知的有效 NSDate 对象并应用相同的 NSDateFormatter 设置来获取一个 NSString 之后,我发现 iOS 6.1 更喜欢这个字符串:@"08/04/2010, 10:43:39 AM"

唯一的区别是日期部分后面的额外逗号。在 iOS 6.1 中使用它会返回一个具有相同上述代码的有效日期。任何人看到这一点并理解为什么会有所不同,或者这是一个好的 Unicode 更改还是 Apple 错误?

【问题讨论】:

  • 您应该向 Apple 提交错误报告。
  • 或者我应该停止使用日期“样式”(短、中、长)并使用确切的格式,例如调用 setDateFormat 吗?在这种情况下,这似乎在两个 iOS 版本中都有效。
  • 这不会让 i18n 变得困难吗?
  • 是的,完全正确。我们试图按照 Apple 推荐的方式来处理传入的日期,将它们转换为不变的(POSIX 英语)语言环境格式,然后将它们发送到具有这些样式的解析器。好吧,看看我们在哪里 :(
  • 欢迎使用机器...

标签: iphone ios objective-c ios6 nsdateformatter


【解决方案1】:

格式样式只能用于将NSDate 对象转换为文本以显示给用户。在以已知格式解析日期字符串时,您必须使用特定格式,而不是样式。使用 en_US_POSIX 区域设置可确保操作系统不会根据用户偏好(例如 24 小时时间设置)调整您指定的格式。

因此,正如您所怀疑的,您需要删除设置日期和时间样式的两个调用,并将它们替换为设置与您需要解析的已知日期/时间字符串匹配的特定格式的调用。

【讨论】:

  • 没有解释为什么这种行为从 iOS 版本改变,但我同意你的逻辑
  • 很可能逗号是结合日期和时间时的一种新行为。这些东西会随着时间的推移而发展或得到修复,这强制执行了在处理固定格式的日期字符串时必须使用固定格式而不是样式的想法。
  • 您在日期格式化 Apple 文档中的哲学可能是正确的吗?我一定错过了。几年前我确实读过那本书。估计不够好:)
  • 查看Q&A 1480。虽然我的陈述更多地基于经验而不是文档中的特定句子。
  • 另外,在初始化日期格式化程序时,您应该只设置一次日期格式。我猜你是出于性能原因缓存日期格式化程序,而不是分配,而是设置日期格式会减慢速度。
【解决方案2】:

通常您不应将格式化的日期输出到文件中,然后再将其解析回来。
日期应存储为长值 UTC(有或没有额外的时区偏移)。 只有在最后一刻,在将日期可视化到 UI 之前,它应该被格式化并应用本地时间。

这不仅是我的经验,Apple DateFormatting Doku 中也有说明。

【讨论】:

  • 我们没有将其输出到文件中。它是从已经像这样格式化的服务发送给我们的。我同意一般来说 UTC 是最好的传递,但在这种情况下,我们会受到遗留服务的摆布。
猜你喜欢
  • 2012-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多