这似乎是一个常见问题,答案很多。在您回答之前,我同时使用了joda-time和atomated,它们非常有用。我的兴趣不是使用什么库,而是澄清了如何在Java中定义RFC模式。
研究
根据我的理解和答案,RFC 3339是ISO 8601的配置文件。PHP明确将RFC 3339日期时间模式定义为Y-m-d\TH:i:sP。如果我们将这个定义转移到Java 7(据我所知),我们最终会得到这个(在此答案中也提到了):
// example"2005-08-15T15:52:01+00:00"
pattern ="yyyy-MM-dd'T'HH:mm:ssXXX";
但是,像这样的几个堆栈溢出答案指出其中一个(或两者)是RFC 3339的正确模式
// example"2016-11-01T20:44:39Z"
pattern ="yyyy-MM-dd'T'HH:mm:ss'Z'";
// example"1937-01-01T12:00:27.87Z"
pattern ="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
为了进一步使事情复杂化,RFC 3339官方文档列出了以下所有示例(我添加了相应的模式):
// 1996-12-19T16:39:57-08:00
pattern ="yyyy-MM-dd'T'HH:mm:ssXXX";
// 1990-12-31T23:59:60Z
pattern ="yyyy-MM-dd'T'HH:mm:ss'Z'";
// 1990-12-31T15:59:60-08:00
pattern ="yyyy-MM-dd'T'HH:mm:ssXXX";
// 1937-01-01T12:00:27.87+00:20
pattern ="yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
旁注:Android不支持时区的XXX模式,但是您可以根据此答案使用ZZZZZ代替。
我认为让我感到困惑的部分原因是,我一直看到RFC 822和RFC 2822分别由一个模式专门提及,因此我认为RFC 3339也可以归结为一个模式匹配:
static String RFC_822 ="EEE, dd MMM yy HH:mm:ss zzz";
static String RFC_2822 ="EEE, dd MMM yyyy HH:mm:ss zzz";
我的结论
与php不同,RFC 3339不能仅使用单个匹配表达式在java中表示。相反,所有这些都是有效的RFC 3339模式,通过SimpleDateFormat解析日期时间字符串时必须检查这些模式:
static String[] RFC_3339_VARIANTS = {
"yyyy-MM-dd'T'HH:mm:ss'Z'",
"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
"yyyy-MM-dd'T'HH:mm:ssXXX",
"yyyy-MM-dd'T'HH:mm:ss.SSSXXX"
};
更新
使事情变得复杂的是,SimpleDateFormat似乎无法正确处理" Z"时区文字。它没有默认采用UTC,而是默认为PST或您的本地时间(我不确定是哪个时间)。这意味着您可能需要用+00:00手动替换'Z'文字以更正此行为?
要旨
如建议的那样,我创建了一个实用程序类Gist,其中包括我当前正在运行的代码。它应在Android上运行,并与Java 7+兼容。请随时提出任何问题或发表评论。如果有足够的兴趣,我可以将其移至Github,以便其他人可以贡献力量:
https://gist.github.com/oseparovic/d9ee771927ac5f3aefc8ba0b99c0cf38
我是否正确理解了这一点?我非常感谢你们对如何在Java 7中解析RFC 3339字符串所做的任何澄清。
您是专门问如何在Java 7中解析这个吗?
对于这个问题,是的。 我不确定在没有XXX支持的情况下如何在Android上完成此操作,因此您可以忽略该注释
支持一个经过充分研究的问题。 如果您可以共享测试的要点(或您愿意的话,可以选择适当的存储库),这样其他人就可以直接复制并进行试验了,那将是很棒的。
谢谢你的客气话。 我很快将在上面的问题中链接到的帮助程序类Gist放在一起。 请随时提出任何问题。 希望有帮助!
由于这是不可能的,并且我还需要严格遵循RFC-3339的内容,因此我创建了一个小工具。 请检查github.com/ethlo/itu(我知道它是一个库,但是只有16K,没有依赖性)
您基本上几乎回答了您自己的问题,只是您的要旨并非在所有情况下都是正确的……也就是说,它需要比您所拥有的两种模式更多的模式(例如处理纳秒级)。
这就是为什么Joda和Java 8具有用于ISO 8601(超集)的特殊解析器的原因。
我知道您不需要引用其他库,但是对于正在使用Java 8或想要显式限制为RFC 3339的其他库(我相信joda iso解析器将使用比rfc 3339更多的格式)有以下库:https://github.com/ethlo/itu