如何解析 DateTime 并将其转换为 RFC 822 日期时间格式?
如何将 DateTime 结构转换为其等效的 RFC 822 日期时间 格式的字符串表示形式并将此字符串表示形式解析回 .NET 中的 DateTime 结构? RFC-822 日期时间格式用于许多规范,例如 RSS 聚合格式 。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
尝试一下:
传递到 DateTime 的 ToString() 方法的“r”格式说明符实际上会生成一个 RFC-1123 格式的日期时间字符串,但也会根据读取 http://www.w3.org/Protocols/rfc822/#z28。 我在创建 RSS 源时使用了这种方法,并且它们根据 http: 上提供的验证器通过验证。 //validator.w3.org/feed/check.cgi。
缺点是,在转换中,它将日期时间转换为 GMT。 要转换回当地时间,您需要应用当地时区偏移量。 为此,您可以使用 TimeZone 类来获取当前时区偏移量,并将“GMT”替换为时区偏移量字符串:
Try this:
The "r" format specifier passed into DateTime's ToString() method actually yields an RFC-1123-formatted datetime string, but passes as an RFC-822 date as well, based on reading the specification found at http://www.w3.org/Protocols/rfc822/#z28. I've used this method in creating RSS feeds, and they pass validation based on the validator available at http://validator.w3.org/feed/check.cgi.
The downside is that, in the conversion, it converts the datetime to GMT. To convert back to local time you would need to apply your local timezone offset. For that, you might use the TimeZone class to get your current timezone offset, and replace "GMT" with a timezone offset string:
这是 C# 中的实现,说明如何解析 DateTime 与其 RFC-822 表示形式之间的转换。 它的唯一限制是日期时间采用协调世界时 (UTC)。 我同意这不是非常优雅的代码,但它完成了工作。
This is an implementation in C# of how to parse and convert a DateTime to and from its RFC-822 representation. The only restriction it has is that the DateTime is in Coordinated Universal Time (UTC). I agree that this is not very elegant code, but it does the job.
按照 Kirk 的想法,我反编译了 System.ServiceModel.Synmination.Rss20FeedFormatter 类 (System.ServiceModel.dll) 的源代码,这里是 RFC 822 日期的 Microsoft 内部解析器格式(我稍微简化了他们的异常处理逻辑以减少依赖性):
第一个看起来不寻常的事情是它们返回
[DateTimeOffset][1]
类而不是DateTime< /代码>。 但当我们阅读更多相关内容时,它似乎完全合乎逻辑 -
DateTimeOffset
存储日期、时间和时区信息(与 RFC 822 格式的字符串完全相同)。 如果您仅返回 DateTime 对象,则该对象位于哪个时区:UTC、本地或解析字符串中指定的时区 - 在某些情况下任何答案都将是错误的。 因此DateTimeOffset
解决了一个重要的不确定性问题。 您可以使用DateTimeOffset.ToUniversalTime()
、DateTimeOffset.ToLocalTime()
方法将其转换为稍后需要的时区。我在几个案例中测试了它,看起来它完美地完成了工作。
但我不确定为什么微软决定将这个实现私有化——它似乎不需要很多支持。
Following Kirk's idea, I decompiled sources for
System.ServiceModel.Syndication.Rss20FeedFormatter
class (System.ServiceModel.dll) and here is Microsoft internal parser for RFC 822 dates format (I slightly simplified their exception handling logic to reduce dependencies):The first thing which may look unusual is that they return
[DateTimeOffset][1]
class instead ofDateTime
. But when we read more about it, it appears to be completely logical -DateTimeOffset
stores date, time and timezone info (exactly as string in RFC 822 format). If you were returning just DateTime object, which timezone it would be in: UTC, local, or the one specified in parsed string - any answer would be wrong for some cases. SoDateTimeOffset
solves an important uncertainty problem. And you can convert it to timezone you need later using methodsDateTimeOffset.ToUniversalTime()
,DateTimeOffset.ToLocalTime()
.I tested it on few cases and it seems it does the job perfectly.
I'm not sure though, why Microsoft decided to make this implementation private - it doesn't seem to require a lot of support.
以下是 Microsoft 在 Rss20FeedFormatter 中的做法。 Oppositional 的代码并没有去掉 GMT 偏移部分中的“:”。 杰夫·伍德曼 (Jeff Woodman) 似乎就是这么做的。 下面的代码也执行此操作(如果不使用 Atom10FeedFormatter.zeroOffset)。
Here is how Microsoft does it in the Rss20FeedFormatter. Oppositional's code doesn't get rid of the ":" in the GMT offset portion. Jeff Woodman's appears to do this. The code below does this as well (if not using Atom10FeedFormatter.zeroOffset).
这是我使用扩展方法的实现:
使用:
Here is my implementation using an extension method:
To use:
根据 Kirk Liemohn 的回答,我成功地使用了这种方法:
示例:
它不尊重 RFC 的完整规范,但它适用于我的用例。
具体来说,它不适用于时区表达,如:“GMT”、“CST”等(请参阅 RFC822 第 5.1 节中的“区域”)。 请参阅 Oleksandr Pshenychnyy 的更好答案。
Based on the answer of Kirk Liemohn, I used this method with success:
Example:
It does not respect full spec of RFC but it works for my use cases.
Specifically, it does not work with timezone express like : "GMT", "CST", etc. (see "zone" in RFC822 Section 5.1). See the better answer of Oleksandr Pshenychnyy.