使用 NSDateFormatter 解析 RFC 822 日期
我正在使用 NSDateFormatter 解析 iPhone 上的 RFC 822 日期。但是,无法以日期格式指定可选元素。 RFC 822 规范中有几个可选部分破坏了日期解析器。如果没有任何结果,我可能必须编写一个自定义解析器来遵守规范。
例如,日期名称在规范中是可选的。因此,这两个日期都是有效的:
Tue, 01 Dec 2009 08:48:25 +0000
使用格式 EEE, dd MMM yyyy HH:mm:ss z
进行解析 01 Dec 2009 08:48:25 +0000
的解析格式为 dd MMM yyyy HH:mm:ss z
这就是我当前使用的:
+ (NSDateFormatter *)rfc822Formatter {
static NSDateFormatter *formatter = nil;
if (formatter == nil) {
formatter = [[NSDateFormatter alloc] init];
NSLocale *enUS = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];
[formatter setLocale:enUS];
[enUS release];
[formatter setDateFormat:@"EEE, dd MMM yyyy HH:mm:ss z"];
}
return formatter;
}
+ (NSDate *)dateFromRFC822:(NSString *)date {
NSDateFormatter *formatter = [NSDate rfc822Formatter];
return [formatter dateFromString:date];
}
并解析日期如下:
self.entry.published = [NSDate dateFromRFC822:self.currentString];
一种方法是尝试两种格式,并采用返回非空值的任何格式。然而,规范中有两个可选部分(日期名称和秒数),并且有 4 种可能的组合。还不错,但有点老套。
I'm using a NSDateFormatter to parse a RFC 822 date on the iPhone. However, there is no way to specify optional elements in the date format. There are a couple of optional parts in the RFC 822 specification which is breaking the date parser. If nothing works out, I'd probably have to write a custom parser to obey the specs.
For example, the day name is optional in the spec. So both these dates are valid:
Tue, 01 Dec 2009 08:48:25 +0000
is parsed with the format EEE, dd MMM yyyy HH:mm:ss z
01 Dec 2009 08:48:25 +0000
is parsed with the format dd MMM yyyy HH:mm:ss z
This is what I am currently using:
+ (NSDateFormatter *)rfc822Formatter {
static NSDateFormatter *formatter = nil;
if (formatter == nil) {
formatter = [[NSDateFormatter alloc] init];
NSLocale *enUS = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];
[formatter setLocale:enUS];
[enUS release];
[formatter setDateFormat:@"EEE, dd MMM yyyy HH:mm:ss z"];
}
return formatter;
}
+ (NSDate *)dateFromRFC822:(NSString *)date {
NSDateFormatter *formatter = [NSDate rfc822Formatter];
return [formatter dateFromString:date];
}
And parsing the date as follows:
self.entry.published = [NSDate dateFromRFC822:self.currentString];
One way is to try both formats, and take whatever returns non null value. However, there are two optional parts in the spec (day name and seconds) and there would be 4 possible combinations. Still not too bad, but it's a bit hacky.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我使用以下方法来解析RFC822日期。我相信它最初来自 MWFeedParser:
I've used the following method to parse RFC822 dates. I believe it originally was from MWFeedParser:
在决定使用哪个格式化程序之前计算显着字符的数量。例如,您给出的两个逗号和空格的数量不同。如果没有已知的格式与计数相匹配,那么您甚至不知道尝试将其解析为日期。
Count the number of salient characters before deciding which formatter to use. For example, the two you give have different numbers of commas and spaces. If no known format matches the counts, then you known not even to try parsing it as a date.
我相信 RFC 822 在日期时间中指定了两个可选组件:星期几和一小时后的秒数。
作为一种破解,可以使用一周中短日的符号:
如果您将日期格式更改为:
EEEDd MMM yyyy HH:mm:ss z
。您将能够在不使用星期几的情况下解析时间。这似乎在逗号后也留有空格。为了安全起见,你不应该盲目地设置这样的符号。您应该使用
setShortWeekdaySymbols
并迭代它们,并在末尾添加逗号。原因是每个地区的情况可能有所不同,而且第一天可能不是星期日。有趣的是,格式
EEE, dd MMM yyyy HH:mm:ss z
将解析没有星期几的时间,但逗号必须在那里,例如, 01 Dec 2009 08:48: 25 +0000
。因此,您可以像史蒂夫说的那样做,但然后去掉这一天并传递给格式化程序。格式中没有逗号似乎不允许星期是可选的。奇怪的。不幸的是,这仍然对格式中的可选 :ss 没有帮助。但它可能允许您拥有两种格式而不是四种。
I believe RFC 822 specifies two optional components in the date time: day of week and the seconds past the hour.
As a hack, it is possible to the symbols for the short days of the week:
If you then change the date format to this:
EEEdd MMM yyyy HH:mm:ss z
. You'll be able to parse times with about without the day of the week. This seems to allow a space after the comma too.To be safe you should not just blindly set the symbols like this. You should get using
setShortWeekdaySymbols
and iterate over them adding the comma at the end. The reason being they are potentially different for each locale and the first day might not be Sunday.Interestingly the format
EEE, dd MMM yyyy HH:mm:ss z
will parse times without the day of week, but the comma must be there, for example, 01 Dec 2009 08:48:25 +0000
. Therefore, you could do something like Steve said but then strip off the day and pass though to the formatter. Not having the comma in the format does not seem to allow the week to be optional. Strange.Unfortunately, this still doesn't help with the optional :ss in the format. But it might allow you to have two formats rather than four.
如果这对其他人有帮助..这是一个基于 Simucal 的答案 的 NSDate+RFC822String.swift 扩展。
它还缓存上次成功使用的日期格式,因为设置 dateFormatter.dateFormat 的成本很高。
In case this is helpful to anyone else.. here is a NSDate+RFC822String.swift extension based on Simucal's answer.
It also caches the last used date format that was successful, since setting the dateFormatter.dateFormat is expensive.