Nil NSDate试图在祖鲁时间从UTC字符串获取日期

时间:2009-08-11 23:02:44

标签: iphone objective-c nsdate utc nsdateformatter

在Objective-C中编写一个iPhone应用程序,我有一个字符串形式的日期(UTC格式,最后用Z表示零UTC偏移,或祖鲁时间),我需要解析为{{ 1}}对象。

一点代码:

NSDate
通过调试器运行此操作,NSDateFormatter* df = [[NSDateFormatter alloc]init]; [df setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSZ"]; NSString* str = @"2009-08-11T06:00:00.000Z"; NSDate* date = [df dateFromString:str];结束date!我假设它与我的日期格式字符串有关。

如何修复它以正确解析日期字符串?

我们的想法是在日期格式文字中设置nil,将日期格式设置为Z

这可行,除非将Z解析为文字,日期丢失了偏移信息,因此不明确,因此被解释为当地时间。

例如,如果要解析的字符串是2009-08-11T06:00:00.000Z(6:00祖鲁时间),它将被解释为当地时间的6:00,然后将应用不正确的偏移量。然后将其解析为2009-08-11T06:00:00.000-600(祖鲁时间12:00),偏移量取决于用户的偏移量。

谢谢!

7 个答案:

答案 0 :(得分:28)

我也有这个问题,我不确定它是否是Apple代码中的API错误,或者我缺乏理解,但我通过在日期字符串中使用小时偏移来解决它。

如果您将示例中的代码更改为:

NSDateFormatter* df = [[NSDateFormatter alloc]init];
[df setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSZ"];
NSString* str = @"2009-08-11T06:00:00.000-0700";   // NOTE -0700 is the only change
NSDate* date = [df dateFromString:str];

现在将解析日期字符串。当然-0700小时是我的抵消,你必须把它改成你的。希望这会有所帮助。

答案 1 :(得分:13)

大多数答案建议您将'Z'视为字面字符。 不要这样做!

Z实际上意味着日期偏移0到UTC(+0000)。

这是根据时区格式ISO8601

  

ISO 8601时区格式:与UTC的常量,特定偏移量,除UTC本身(“Z”)外,其格式始终相同。

     

“ - 08:00”

     

“Z”

您要做的是为NSDateFormatter使用以下格式:

 NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
                                  // 2013-11-18T23:00:00.324Z
                                  [formatter setTimeZone:[NSTimeZone localTimeZone]];
                                  [formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"];
                                  return formatter;

重复 Z 五次,告诉格式化程序在解析字符串时使用ISO8601。

加成:

  • 对RFC 822 GMT格式使用一到三个 Z
  • 使用四个 Z 本地化的GMT格式。

有关详细信息,请查看this文档。

答案 2 :(得分:4)

我认为你需要在格式字符串中放置Z的单引号,因为Z实际上对格式化程序意味着什么,而你希望它代表一个文字字符。

    [df setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];

答案 3 :(得分:2)

无需操纵字符串。只需在NSDateFormatter上设置时区(以及您所在的区域设置):

NSDateFormatter * formatter = [[NSDateFormatter alloc] init];
[formatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
[formatter setLocale:[NSLocale systemLocale]];
[formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];

根据需要解析日期字符串:

NSDate * value = [formatter dateFromString:@"2012-03-01T23:08:25.000Z"];
NSLog(@"%@", value); // prints 2012-03-01 23:08:25 +0000

答案 4 :(得分:1)

您可以使用此方法从UTC获取日期。

+ (NSDate*)getDateFromUTCDateTimeString:(NSString*)dateString {

NSDateFormatter *isoDateFormatter = [[NSDateFormatter alloc] init];

[isoDateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];

[isoDateFormatter setTimeZone:[NSTimeZone  timeZoneWithAbbreviation:@"UTC"]];

NSDateFormatter *userFormatter = [[NSDateFormatter alloc] init];

[userFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];

[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];

[dateFormatter setTimeZone:[NSTimeZone  timeZoneWithAbbreviation:@"UTC"]];

NSDate *date = [isoDateFormatter dateFromString:dateString];

return [dateFormatter dateFromString:[userFormatter stringFromDate:date]];

}

答案 5 :(得分:0)

这可能对你有帮助..“Z”是时区代码的文字。尝试使用“o”(字母,而不是零)。文字“o”表示UTC偏移。我曾经遇到过这个问题,我希望这能帮助你。

答案 6 :(得分:-1)

-(NSDate*)dateFromZulu:(NSString*)str {
    if (str == nil) {
        NSLog(@"Error getting date");
        return [NSDate date];
    }

    NSDateFormatter *f = [[NSDateFormatter alloc] init];
    [f setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss Z"];
    NSDate *ret = [f dateFromString:[str stringByReplacingOccurrencesOfString:@"Z" withString:@" +0000"]];
    [f release];

    if (ret == nil) {
        ret = [NSDate date];
        NSLog(@"Error formatting date (%@)",str);       
    }   
    return ret;     
}