关于iPhone:NSDateFormatter在OS 4.0中返回nil

NSDateFormatter returning nil in OS 4.0

我在OS 3.x上使用以下代码

1
2
3
4
5
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中,varialble theDate为零。

我浏览了类参考,没有看到使用这些特定方法对iOS4进行过任何过时或不同的实现。 我遗漏了什么?


我发现如果您采用这种方式,它会起作用(请参见下文)。关键是使用方法:
- [NSDateFormatter getObjectValue:forString:range:error:]

代替

-[NSDateFormatter dateFromString]

完整的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
+ (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;
}


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

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

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

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

希望能有所帮助。


该代码将删除多余的冒号,如AtomRiot所述:

Converting it from:

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

to:

  • NSString *stringDate = @"2010-06-21T20:06:36+0000";
1
2
3
4
5
6
7
// 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


看来,Apple文档是"棘手的":

The format string uses the format
patterns from the Unicode standard
(this reference is to version tr35-6
for Mac OS X v10.5; for Mac OS X v10.4
use version tr35-4).

iOS: The v10.0 compatibility mode is
not available on iOS—only the 10.4
mode is available.

根据版本tr35-4:

Use 1 for GMT format, 2 for RFC 822

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

但是根据Unicode标准:

Use one to three letters for RFC 822, four letters for GMT format.

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

因此,看来iOS 4使用的是tr35-6-Unicode标准,这就是为什么+00:00现在对'Z'失败的原因。

我在NSDateFormatter中尝试对" ZZZZ"使用-08:00,但在iOS 4中却失败了。但是,GMT-08:00可以正常工作。似乎现在需要时区(GMT),而不是在iOS 3中可能是时区。


我最近遇到了这个问题。我最终使用了Peter Hosey的ISO8601解析器。它可以在这里找到:http://boredzo.org/iso8601unparser/


我得到的格式在RFC 822和GMT之间。如果我将" +00:00"更改为" +0000",则可以在格式上使用" Z"。如果我将其更改为" GMT + 00:00",则可以使用ZZZZ正确获取数据。似乎已经删除了一些东西来处理这种混合动力,因为它在OS 3.x之前对我有用。


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


我使用它很简单:

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

这很有效。当NSDateFormatter类从NSObject子类化时,我不明白它们如何不赞成使用init方法


我的应用程式和NSDateFormatter的Null值都存在相同的问题。

我发现我的问题如下:

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

似乎NO LONGER格式的ZZZ部分当时接受了冒号:。

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

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

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

希望这可以帮助其他人。


看来NSDateFormatter变得非常挑剔。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
-(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;
}


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

Elfred wrote: I ran into this issue recently. I ended up using Peter Hosey's ISO8601 parser. It is available here: http://boredzo.org/iso8601unparser/


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

查看NSDateFormatter文档时,我看到:

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

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


对我来说很好。

它仍然可以在真实设备上正常运行吗?

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