简体   繁体   English

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

[英]Is there a simple way of converting an ISO8601 timestamp to a formatted NSDate?

If I use the following code: 如果我使用以下代码:

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]);

It is successfully converted to a Date object, however, I cannot seem to format it any other way than yyyy-MM-dd'T'HH:mm , ie what gets logged is 2010-01-28T15:22:23 它已成功转换为Date对象,但是,我似乎无法以任何其他方式格式化它yyyy-MM-dd'T'HH:mm ,即记录的是2010-01-28T15:22:23

If I change the dateFormat to say [dateFormatter setDateFormat:@"yyyy-MMMM-d'T'HH:mm"]; 如果我将dateFormat更改为[dateFormatter setDateFormat:@"yyyy-MMMM-d'T'HH:mm"]; the Date object is null... Date对象为null ...

So my ultimate question is how to format an ISO8601 timestamp from a SQL database to use, for instance, NSDateFormatterMediumStyle to return "January 1, 2010"? 所以我的最终问题是如何格式化SQL8数据库中的ISO8601时间戳,例如,使用NSDateFormatterMediumStyle返回“2010年1月1日”?

I have a similiar but slightly more complex problem, and I've found a very simple solution! 我有一个类似但稍微复杂的问题,我找到了一个非常简单的解决方案!

The problem: My incoming ISO8601 dates look like this: 2006-06-14T11:06:00+02:00 They have a timezone offset at the end. 问题:我传入的ISO8601日期如下所示: 2006-06-14T11:06:00+02:00他们最后有一个时区偏移量。

The solution: Use Peter Hosey's ISO8601DateFormatter which you can download from here . 解决方案:使用Peter Hosey的ISO8601DateFormatter ,您可以从这里下载。

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

and

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

Here is sample code from apple 这是来自apple的示例代码

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

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

You need another formatter to handle the output. 您需要另一个格式化程序来处理输出。 Put this after your code: 把它放在你的代码之后:

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

仅举几例,自iOS 6.0起,您可以使用以下格式:

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

I have a very fast C implementation of parsing ISO8601 NSStrings to NSDates in SAMCategories . 我有一个非常快速的C实现,将ISO8601 NSStrings解析为SAMCategories中的NSDates You can install it with CocoaPods or just copy the files to your project. 您可以使用CocoaPods安装它,或者只是将文件复制到您的项目中。

Here's how to use it: 以下是如何使用它:

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

It's very robust and supports missing timezones, etc. Like my comment above said, NSDateFormatter was very slow for me when parsing lots of dates. 它非常强大并且支持缺少时区等。就像我上面的评论所说,在解析大量日期时,NSDateFormatter对我来说非常慢。 Switching to this implementation helped an immense amount. 切换到这种实现有很大帮助。

This code is used in 6 production apps (including Hipstamatic and Roon ) that I've worked on with no known issues. 此代码用于我已经处理过的6个生产应用程序(包括Hipstamatic和Roon ),没有任何已知问题。 There is a test suite to prevent regression. 有一个测试套件可以防止回归。

In short, I think this is the best way to parse ISO8601 strings in Objective-C. 简而言之,我认为这是在Objective-C中解析ISO8601字符串的最佳方法。


A short aside, if you're concerned about performance and transfer, sending integers instead of ISO8601 strings is greatly preferred. 简而言之,如果您关注性能和传输,则首选发送整数而不是ISO8601字符串。 You can simply convert them into dates with [NSDate dateWithTimeIntervalSince1970:yourInteger] . 您可以使用[NSDate dateWithTimeIntervalSince1970:yourInteger]将它们转换为日期。 Performance is as fast as you can make it and there are less characters to transfer over the wire. 性能和您一样快,并且通过线路传输的字符更少。

I should note that last time I checked Apples NSDate methods didn't support ISO8601. 我应该注意,上次我检查苹果NSDate方法不支持ISO8601。 I still have a bug with Apple about putting official support in. 我仍然有一个关于提供官方支持的苹果公司的错误。

+ (id)dateWithNaturalLanguageString:(NSString *)string

will properly (last time I ran it) parse and create an NSDate object from an ISO801 string, though the documentation says you shouldn't use it, it's worked on all ISO8601 dates I've tried so far. 将正确(上次我运行它)解析并从ISO801字符串创建一个NSDate对象,虽然文档说你不应该使用它,它适用于我迄今为止尝试过的所有ISO8601日期。

@danielbeard answer worked for me. @danielbeard的答案对我有用。 However you need to include the timezone otherwise it converts a UTC date into your current timezone which isn't what you want. 但是,您需要包含时区,否则它会将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;
}

@Thread队长试试这个格式:“yyyy-MM-dd'T'HH:mm:ss.SSS”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM