有没有一种简单的方法将ISO8601时间戳转换为格式化的NSDate?

时间:2010-02-04 16:16:12

标签: objective-c nsdate nsdateformatter iso8601

如果我使用以下代码:

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];   
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm"];
NSDate *myDate = [dateFormatter dateFromString:@"2010-01-28T15:22:23.863"];
NSLog(@"%@", [dateFormatter stringFromDate:myDate]);

它已成功转换为Date对象,但我似乎无法以yyyy-MM-dd'T'HH:mm之外的其他方式对其进行格式化,即记录的内容为2010-01-28T15:22:23

如果我将dateFormat更改为[dateFormatter setDateFormat:@"yyyy-MMMM-d'T'HH:mm"];,则Date对象为空...

所以我的最终问题是如何从SQL数据库格式化ISO8601时间戳,例如使用NSDateFormatterMediumStyle来返回“2010年1月1日”?

8 个答案:

答案 0 :(得分:42)

我有一个类似但稍微复杂的问题,我找到了一个非常简单的解决方案!

问题: 我传入的ISO8601日期如下所示:2006-06-14T11:06:00+02:00他们最后有一个时区偏移量。

解决方案: 使用Peter Hosey的 ISO8601DateFormatter ,您可以从here下载。

ISO8601DateFormatter *formatter = [[ISO8601DateFormatter alloc] init];
NSDate *theDate = [formatter dateFromString:dateString];
[formatter release], formatter = nil;

ISO8601DateFormatter *formatter = [[ISO8601DateFormatter alloc] init];
NSString *dateString = [formatter stringFromDate:[twitch dateTwitched]];
[formatter release], formatter = nil;

答案 1 :(得分:19)

您需要另一台格式化程序来处理输出。把它放在你的代码之后:

NSDateFormatter *anotherDateFormatter = [[NSDateFormatter alloc] init];   
[anotherDateFormatter setDateStyle:NSDateFormatterLongStyle];
[anotherDateFormatter setTimeStyle:NSDateFormatterShortStyle];
NSLog(@"%@", [anotherDateFormatter stringFromDate:myDate]);

答案 2 :(得分:19)

以下是来自apple的示例代码

    NSDateFormatter * formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"];
    NSDate *date = [formatter dateFromString:dateString];

链接:https://developer.apple.com/library/ios/#qa/qa1480/_index.html

答案 3 :(得分:12)

请注意,自iOS 6.0起,您可以使用以下格式:

 yyyy-MM-dd'T'HH:mm:ssZZZZZ

答案 4 :(得分:6)

我有一个非常快速的C实现,即在SAMCategories中将ISO8601 NSStrings解析为NSDates。您可以使用CocoaPods安装它,或者只是将文件复制到项目中。

以下是如何使用它:

[NSDate sam_dateFromISO8601String:@"2013-08-24T06:51:21-07:00"]

它非常强大并且支持缺少时区等。就像my comment above所说的那样,在解析大量日期时,NSDateFormatter对我来说非常慢。切换到这种实现有很大的帮助。

此代码用于6个生产应用程序(包括Hipstamatic和Roon),我已经处理过没有已知问题。有一个test suite可以防止回归。

简而言之,我认为这是在Objective-C中解析ISO8601字符串的最佳方法。


简而言之,如果您关注性能和传输,则首选发送整数而不是ISO8601字符串。您只需将其转换为[NSDate dateWithTimeIntervalSince1970:yourInteger]的日期即可。性能和您一样快,并且通过线路传输的字符更少。

答案 5 :(得分:5)

我应该注意,上次检查Apples NSDate时,方法不支持ISO8601。我还有一个关于将官方支持放入苹果的错误。

+ (id)dateWithNaturalLanguageString:(NSString *)string

将正确(上次我运行它)解析并从ISO801字符串创建一个NSDate对象,虽然文档说你不应该使用它,它适用于我迄今为止尝试过的所有ISO8601日期。

答案 6 :(得分:3)

@danielbeard的回答对我有用。但是,您需要包含时区,否则它会将UTC日期转换为您当前的时区,而这不是您想要的。

- (NSDate *) dateFromISO8601DateString:(NSString *) dateString {
    NSDateFormatter * dateFormatter = [NSDateFormatter new];
    dateFormatter.timeZone = [NSTimeZone timeZoneWithName:@"UTC"];
    [dateFormatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"];
    NSDate * date = [dateFormatter dateFromString:dateString];
    return date;
}

答案 7 :(得分:2)

@Thread队长 试试这个格式:" yyyy-MM-dd' H&H:mm:ss.SSS"