【问题标题】:NSDateFormatter returning nil in OS 4.0NSDateFormatter 在 OS 4.0 中返回 nil
【发布时间】:2014-06-14 16:30:50
【问题描述】:

我在 OS 3.x 上运行了以下代码

NSString *stringDate = @"2010-06-21T20:06:36+00:00";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZ"];
NSDate *theDate = [dateFormatter dateFromString:stringDate];
NSLog(@"%@",[dateFormatter stringFromDate:theDate]);

但现在在iOS4模拟器下最新的xcode 3.2.3中,变量theDate为nil。

我查看了类参考,并没有看到使用这些特定方法为 iOS4 弃用或以不同方式实现的任何内容。我遗漏了什么?

【问题讨论】:

  • 似乎如果我从 stringDate 中删除“+00:00”,然后从格式中删除“Z”,它将正常工作,但这并不是一个真正的选择,因为动态数据我get 附加了时区,我真的不想为我得到的每个日期撕掉那部分。而且我找不到任何文件说不再以这种方式支持时区。
  • 我想我明白了。我得到的格式介于 RFC 822 和 GMT 之间。如果我将“+00:00”更改为“+0000”,那么我可以在格式上使用“Z”。如果我将其更改为“GMT+00:00”,那么我可以使用 ZZZZ 正确获取数据。似乎已经剥离了一些东西来处理这种混合,因为它以前在 OS 3.x 上为我工作。

标签: iphone ios4 nsdateformatter


【解决方案1】:

我发现如果你这样做,它会起作用(见下文)。关键是使用方法: - [NSDateFormatter getObjectValue:forString:range:error:]

而不是

-[NSDateFormatter dateFromString]

完整代码:

+ (NSDate *)parseRFC3339Date:(NSString *)dateString 
{
    NSDateFormatter *rfc3339TimestampFormatterWithTimeZone = [[NSDateFormatter alloc] init];
    [rfc3339TimestampFormatterWithTimeZone setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"] autorelease]];
    [rfc3339TimestampFormatterWithTimeZone setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZ"];

    NSDate *theDate = nil;
    NSError *error = nil; 
    if (![rfc3339TimestampFormatterWithTimeZone getObjectValue:&theDate forString:dateString range:nil error:&error]) {
        NSLog(@"Date '%@' could not be parsed: %@", dateString, error);
    }

    [rfc3339TimestampFormatterWithTimeZone release];
    return theDate;
}

【讨论】:

  • 谢谢。 dateFromString: 和 getObjectValue:forSting:range:error: 行为确实不同。后者确实可以正常工作,而前者在同一字符串(包括冒号)上阻塞。
  • 只是补充一下,我正在使用此代码来解析来自 JSON Web 服务的日期字符串。它工作得很好,但是必须为每条记录初始化一个 NSDateFormatter 使得这个过程非常慢(18 秒,解析 5,000 条 JSON 记录,每条都包含一个日期字符串)。我将 NSDateFormatter 移到了我的“加载 JSON 记录”函数中,因此它只初始化了一次,并且性能好多更好(加载 5,000 条 JSON 记录的时间不到 1 秒)。
【解决方案2】:

您的设备设置为 24 小时制还是 12 小时制?

这听起来像是一个疯狂的问题,但我刚刚遇到了这个错误 - dateformatter 将根据当前的语言环境调整您的格式字符串,其中包括时间格式设置。

您可以通过添加此行来强制它忽略它们:

dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];

希望对您有所帮助。

【讨论】:

  • 嗯,我看不出有什么不同。仍然从 dateFromString 调用中获取空值。
  • 这是 2.x 时代的一个错误。不确定它是否仍然存在,因为我最终“手动”解析了字符串。
  • 它肯定仍然存在 - 虽然它不再是一个错误,但他们已经记录了它;-)
  • 这对我有用。这个苹果链接解释了一切:developer.apple.com/iphone/library/qa/qa2010/qa1480.html
  • +1 也为我工作。浪费了3个多小时。希望我早点看到这个答案。
【解决方案3】:

此代码将删除 AtomRiot 描述的额外冒号:

转换自:

  • NSString *stringDate = @"2010-06-21T20:06:36+00:00";

收件人:

  • NSString *stringDate = @"2010-06-21T20:06:36+0000";
// Remove colon in timezone as iOS 4+ NSDateFormatter breaks
if (stringDate.length > 20) {
    stringDate = [stringDate stringByReplacingOccurrencesOfString:@":"
                                                       withString:@""
                                                          options:0
                                                            range:NSMakeRange(20, stringDate.length-20)];
}

更多详情请见:https://devforums.apple.com/thread/45837

【讨论】:

    【解决方案4】:

    我最近遇到了这个问题。我最终使用了 Peter Hosey 的 ISO8601 解析器。可在此处获得:http://boredzo.org/iso8601unparser/

    【讨论】:

    • 这救了我的命,谢谢。我更喜欢使用特定的解析器而不是修改输入日期字符串。
    【解决方案5】:

    Apple 文档似乎很“棘手”:

    格式字符串使用格式 来自Unicode 标准的模式 (此参考是版本 tr35-6 适用于 Mac OS X v10.5; 适用于 Mac OS X v10.4 使用版本tr35-4)。

    iOS:v10.0兼容模式为 在 iOS 上不可用 - 只有 10.4 模式可用。

    根据版本tr35-4

    1 表示 GMT 格式,2 表示 RFC 822

    Z{1} GMT-08:00
    Z{2} -0800

    但根据Unicode标准:

    RFC 822 使用一到三个字母,GMT 格式使用四个字母。

    Z{1,3} -0800
    Z{4} GMT-08:00

    所以看起来 iOS 4 正在使用 tr35-6 - Unicode 标准,这就是为什么 +00:00 现在对“Z”失败了。

    我在我的 NSDateFormatter 中尝试 -08:00 针对“ZZZZ”,但在 iOS 4 中失败GMT-08:00,但是,确实有效。似乎时区 (GMT) 现在是必需的,而不是像在 iOS 3 中那样是可选的。

    【讨论】:

      【解决方案6】:

      我得到的格式介于 RFC 822 和 GMT 之间。如果我将“+00:00”更改为“+0000”,那么我可以在格式上使用“Z”。如果我将其更改为“GMT+00:00”,那么我可以使用 ZZZZ 正确获取数据。似乎已经剥离了一些东西来处理这种混合,因为它以前在 OS 3.x 上为我工作。

      【讨论】:

        【解决方案7】:

        我从 dataFormat @"yyyy'-'MM'-'dd'T'HH':'mm':'ss'+'hh:mm" 中获取值;

        【讨论】:

        • 时区之前的一切都没有给我带来任何麻烦。这只是时区部分。而且我正在获取时区数据,所以我必须在解析之前稍微更改输入
        【解决方案8】:

        我觉得很好。

        它在真实设备上仍然可以正常工作吗?

        如果是,请为模拟器提交错误报告,否则为 iOS 4 提交错误报告。

        【讨论】:

        • 我还不能在设备上测试,我的现在搞砸了。我希望这只是一个模拟器问题,但 dateformatter 似乎并不是模拟器会遇到的问题。
        • 好的,刚刚在设备上尝试了此代码,我看到与模拟器相同的行为。 :(
        【解决方案9】:

        我只是在调试这个完全相同的问题。我有与您在 3.x 而不是 4.0 中工作的相同日期字符串。相同的症状。

        查看 NSDateFormatter 文档时,我看到:

        初始化日期格式化程序 – init 在 iPhone OS 2.0 到 iPhone OS 3.2 中可用

        这表示 iOS 4.0 已弃用 init 方法。我不确定那是什么意思。

        【讨论】:

        • 我在阅读类参考时也看到了这一点,但它没有其他提及它的含义。而且 Xcode 并没有将其标记为 deprecated。
        【解决方案10】:

        Elfred 发布的链接起到了作用。在将我的应用程序从 3.1.3 转换到 iOS4 时,我偶然发现了同样的问题。该链接包含 ISO8601DateFormatter 类,这是一个比我自己的日期实用程序类更出色的扩展。

        Elfred 写道: 我最近遇到了这个问题。我最终使用了 Peter Hosey 的 ISO8601 解析器。可在此处获得:http://boredzo.org/iso8601unparser/

        【讨论】:

          【解决方案11】:

          似乎 NSDateFormatter 变得非常挑剔。

          -(void)dateFormatterTests {
              NSDateFormatter *formatter;
          
              formatter = [[NSDateFormatter alloc] init];
          
          #ifdef WORKS
              [formatter setDateFormat:@"yyyy-MM-dd"];
          #elif defined(ALSO_WORKS)
              [formatter setDateFormat:@"yyyy MM dd"];
              [formatter setLenient:YES];
          #else // DOESN'T WORK
              [formatter setDateFormat:@"yyyy MM dd"];
          #endif
          
              // Works per comments above
              NSLog(@"dFS: %@", [formatter dateFromString:@"2010-01-13"]);  
              // Never works with any of the above formats
              NSLog(@"dFS: %@", [formatter dateFromString:@"2010-01-13 22:00"]); 
          
              [formatter release]; formatter = nil;
          }
          

          【讨论】:

          • 此代码不考虑时区。我得到了特定格式的时区,我无法更改它。
          • 对不起。这篇文章的重点是在你认为它应该产生某些东西的情况下,例如当只解码一个日期,但也在字符串中添加一个时间时,格式化程序会返回 nil。我很高兴你能成功。
          【解决方案12】:

          我的应用程序也遇到了同样的问题Null Value from NSDateFormatter

          我发现我的问题如下:

          我正在向我的应用发送这样的日期和时间:07/16/2010 04:21:00 +00:00,格式化程序如下:[dateFormatter setDateFormat:@"MM/dd/yyyy HH:mm:ss ZZZ"]

          格式中的ZZZ 部分似乎不再接受冒号:在时间上。

          作品:07/16/2010 04:21:00 +0000

          不起作用:07/16/2010 04:21:00 +00:00

          为了支持现有的应用程序,我所做的只是在字符串中搜索+00:00 部分并将其替换为+0000

          希望这可能对其他人有所帮助。

          【讨论】:

            【解决方案13】:

            我使用它很简单:

            date_formatter = [[NSDateFormatter alloc] init];
                    [date_formatter setDateStyle:NSDateFormatterShortStyle];
                    [date_formatter setTimeStyle:NSDateFormatterNoStyle];
            

            这很好用。当 NSDateFormatter 类从 NSObject 子类化时,我不明白他们如何弃用 init 方法

            【讨论】:

              猜你喜欢
              • 2011-03-13
              • 1970-01-01
              • 2017-04-24
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多