2

我们的 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 错误?

4

2 回答 2

1

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

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

于 2013-02-08T15:42:09.507 回答
0

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

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

于 2013-02-08T15:56:58.123 回答