iOS 6.1 NSDateFormatter自iOS 5中断解析后发生了更改



我们的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提供了一个零,因此它们用于解析的内容发生了变化。发行说明中没有提及NSDateFormatter的更改。互联网研究表明,他们可能已经更改为使用新的Unicode UTS Locale解析标准。很明显,他们改变了一些。在摆弄代码并获取已知的有效NSDate对象并应用相同的NSDateFormatter设置来获取NSString之后,我发现iOS 6.1反而喜欢这个字符串:@"08/04/2010,10:43:39 AM"

唯一的区别是日期部分后面多了一个逗号。在iOS 6.1中使用它会返回具有相同上述代码的有效日期。有人看到这一点并理解为什么会有不同,或者这是Unicode的变化还是苹果的错误吗?

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

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

通常情况下,您不应该将格式化的Date输出到文件中,然后希望将其解析回来
日期应存储为长值UTC(带或不带额外的时区偏移)。只有在最后一刻,在将日期可视化到UI之前,才应该对其进行格式化并应用本地时间

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

最新更新