我的 NSDateFormatter 仅适用于 iPhone 模拟器

Posted

技术标签:

【中文标题】我的 NSDateFormatter 仅适用于 iPhone 模拟器【英文标题】:my NSDateFormatter works only in the iPhone simulator 【发布时间】:2009-05-08 08:56:03 【问题描述】:

我使用 NSDateFormatter,它在模拟器中运行良好,但在 iPhone 中运行时我得到一个 nil。我硬编码了日期以确保格式,但无论如何它都失败了。

NSString *strPubDate = @"Fri, 8 May 2009 08:08:35 GMT";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
[dateFormatter setDateFormat:@"EEE, d MMM yyyy HH:mm:ss Z"];

NSDate *myDate = [dateFormatter dateFromString:strPubDate];

我在 iPhone 上尝试了不同的区域设置、语言等。知道出了什么问题吗?

【问题讨论】:

【参考方案1】:

此代码似乎可以针对“GMT”标签正常工作。

NSString *strPubDate = @"Fri, 8 May 2009 08:08:35 GMT";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"EEE, d MMM yyyy HH:mm:ss zzzz"];
NSDate *myDate = [dateFormatter dateFromString:strPubDate];

RFC822 Date and Time specs 使用了一些“区域”标签,我找到了正确的符号来解析“GMT”标签Format String for the iPhone NSDateFormatter

z~zzz:(特定 GMT 时区缩写) zzzz:(特定 GMT 时区名称) Z:+0000(RFC 822 时区

感谢您的帮助!

【讨论】:

【参考方案2】:

如果您需要使用特定的日期格式,您可能希望“手动”解析它,而不是使用NSDateFormatter。它的行为确实会根据语言环境等发生变化,并且存在一些错误,特别是当您的字符串中有时区时。

话虽如此,找出问题所在的一种选择可能是使用getObjectValue:forString:range:error: 方法而不是dateFromString:。这样您就可以得到一个NSError 对象,(理论上)它会告诉您问题所在。

顺便说一句,您不需要 NSDateFormatterBehavior10_4 行。 iPhone OS 仅支持 10.4+ 选项,但如果您在模拟器中使用“旧”样式,则不会出现任何错误。

【讨论】:

我尝试了getObjectValue:forString:range:error:,得到了一个Error Domain=NSCocoaErrorDomain Code=2048 "Formatting error.",这对我来说意义不大。所以我手动解析它,这似乎是更安全的方法。感谢您的回答【参考方案3】:

我最近也遇到了这个问题(ios5)。 我还需要设置NSDateFormatter 的语言环境才能在设备上工作。 没有这个,[dateFormatServer dateFromString:dateServer] 将返回 null。

NSString *dateServer = @"Fri, 8 May 2009 08:08:35 GMT";

NSDateFormatter *dateFormatServer = [[NSDateFormatter alloc] init];
[dateFormatServer setDateFormat:@"EEE, d MMM yyyy HH:mm:ss zzzz"];

NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_GB"];
[dateFormatServer setLocale:locale];
[locale release];

NSDate * date = [dateFormatServer dateFromString:dateServer];

【讨论】:

【参考方案4】:

没有什么特别突出的,但为了帮助调试,您可以尝试为 NSDateFormatter 提供一个日期对象,并查看生成的字符串与您尝试解析的字符串是否有任何细微差别。

【讨论】:

【参考方案5】:

当我解析一个以“GMT”结尾的日期字符串时,我使用的是“zzz”格式,而不是“Z”。

【讨论】:

【参考方案6】:

我赞同 Manuel Spuhler 关于手动解析的建议——不是我最喜欢的选项,但 Objective-C 的选项太复杂了(并且缺乏错误报告——任何错误都会吐出nil,没有提示错误) .

对我有用的一件事是使用 C 的 strptime 来解耦日期,然后将其重构为 NSDate 对象。例如,下面的代码将接收到的字符串接收为“星期一,2009 年 9 月 28 日 18:13:50 UTC”,并将其转换为适应本地时间的 UTC 时间的 NSDate 对象:

    struct tm time;
    strptime([currentStringValue UTF8String], "%A, %d-%b-%y %H:%M:%S %z", &time);   
    NSDate* myDate = [NSDate dateWithString:
        [NSString stringWithFormat:@"%04d-%02d-%02d %02d:%02d:%02d +0000",
            time.tm_year+1900, time.tm_mon+1, time.tm_mday,
            time.tm_hour, time.tm_min, time.tm_sec]
    ];

(可以通过添加其他struct tm参数而不是+0000固定时区来处理其他区域,详见time.h entry on wikipedia):

【讨论】:

很遗憾,dateWithString: 在 OS X 上已弃用,在 iOS 上不受支持。【参考方案7】:

strptime 也救了我。

struct tm time;
if (strptime([modDateString UTF8String], "%A, %d %b %Y %H:%M:%S", &time)) 
            NSString *rDate=[NSString stringWithFormat:@"%04d-%02d-%02d %02d:%02d:%02d +0000",
                             time.tm_year+1900, time.tm_mon+1, time.tm_mday,
                             time.tm_hour, time.tm_min, time.tm_sec];

此代码适用于 HTTP 日期,例如 2010 年 4 月 15 日星期四 13:53:56 GMT 和 2009 年 5 月 8 日星期五 08:08:35 GMT,这是原始问题

【讨论】:

以上是关于我的 NSDateFormatter 仅适用于 iPhone 模拟器的主要内容,如果未能解决你的问题,请参考以下文章

scikit-learn joblib 错误:多处理池 self.value 超出“i”格式代码的范围,仅适用于大型 numpy 数组

为啥我的 charFormat 样式仅适用于选择,并且仅适用于特定方向的选择?

Cloudfront CORS仅适用于子域

我的 foreach 仅适用于第一个实例 [重复]

我的拐角半径仅适用于一个拐角

Cloudfront CORS 仅适用于子域