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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2201216/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 22:53:36  来源:igfitidea点击:

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

objective-cnsdatensdateformatteriso8601

提问by rson

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 Dateobject, however, I cannot seem to format it any other way than yyyy-MM-dd'T'HH:mm, i.e. 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"];the Date object is null...

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

So my ultimate question is how to format an ISO8601 timestamp from a SQL database to use, for instance, NSDateFormatterMediumStyleto return "January 1, 2010"?

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

采纳答案by osteven

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

回答by Matthew

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:00They have a timezone offset at the end.

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

The solution:Use Peter Hosey's ISO8601DateFormatterwhich 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;

回答by david

Here is sample code from 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

回答by Marcin

Just to mention that since iOS 6.0 you can use this format:

只是提一下,从 iOS 6.0 开始,您可以使用这种格式:

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

回答by Sam Soffes

I have a very fast C implementation of parsing ISO8601 NSStrings to NSDates in SAMCategories. You can install it with CocoaPods or just copy the files to your project.

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

Here's how to use it:

以下是如何使用它:

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

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

It's very robust and supports missing timezones, etc. Like my comment abovesaid, NSDateFormatter was very slow for me when parsing lots of dates. Switching to this implementation helped an immense amount.

它非常健壮,支持缺少时区等。就像我上面的评论所说,NSDateFormatter 在解析大量日期时对我来说非常慢。切换到此实现有很大帮助。

This code is used in 6 production apps (including Hipstamatic and Roon) that I've worked on with no known issues. There is a test suiteto prevent regression.

此代码用于 6 个生产应用程序(包括 Hipstamatic 和Roon),我一直在使用这些应用程序,没有任何已知问题。有一个测试套件可以防止回归。

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. You can simply convert them into dates with [NSDate dateWithTimeIntervalSince1970:yourInteger]. Performance is as fast as you can make it and there are less characters to transfer over the wire.

简而言之,如果您关心性能和传输,则非常喜欢发送整数而不是 ISO8601 字符串。您可以简单地将它们转换为日期[NSDate dateWithTimeIntervalSince1970:yourInteger]。性能尽可能快,并且通过网络传输的字符更少。

回答by Colin Wheeler

I should note that last time I checked Apples NSDatemethods didn't support ISO8601. I still have a bug with Apple about putting official support in.

我应该注意,上次我检查 ApplesNSDate方法不支持 ISO8601。我仍然对 Apple 有关于提供官方支持的错误。

+ (id)dateWithNaturalLanguageString:(NSString *)string

+ (id)dateWithNaturalLanguageString:(NSString *)string

will properly (last time I ran it) parse and create an NSDateobject 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.

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

回答by gngrwzrd

@danielbeard answer worked for me. However you need to include the timezone otherwise it converts a UTC date into your current timezone which isn't what you want.

@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;
}

回答by Andi Utzinger

@Thread captain Try this Format : "yyyy-MM-dd'T'HH:mm:ss.SSS"

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