将符合ISO 8601的字符串转换为java.util.Date [英] Converting ISO 8601-compliant String to java.util.Date
问题描述
我正在尝试将 ISO 8601 格式的字符串转换为java.util.Date。
I am trying to convert an ISO 8601 formatted String to a java.util.Date.
如果与区域设置(比较样本)一起使用,我发现yyyy-MM-dd'T'HH:mm:ssZ的格式符合ISO8601标准。
但是,使用java.text.SimpleDateFormat,我无法转换格式正确的字符串2010-01-01T12:00:00 + 01:00。我必须先转换为2010-01-01T12:00:00 + 0100,没有冒号。
所以,目前的解决方案是
I found the pattern "yyyy-MM-dd'T'HH:mm:ssZ" to be ISO8601-compliant if used with a Locale (compare sample). However, using the java.text.SimpleDateFormat, I cannot convert the correctly formatted String "2010-01-01T12:00:00+01:00". I have to convert it first to "2010-01-01T12:00:00+0100", without the colon. So, the current solution is
SimpleDateFormat ISO8601DATEFORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.GERMANY);
String date = "2010-01-01T12:00:00+01:00".replaceAll("\\+0([0-9]){1}\\:00", "+0$100");
System.out.println(ISO8601DATEFORMAT.parse(date));
这显然不是很好。我缺少一些东西,还是有更好的解决方案?
which obviously isn't that nice. Am I missing something or is there a better solution?
答案
谢谢到JuanZe的评论,我发现 Joda-Time 魔法,它也是这里描述。
所以,解决方案是
Thanks to JuanZe's comment, I found the Joda-Time magic, it is also described here. So, the solution is
DateTimeFormatter parser2 = ISODateTimeFormat.dateTimeNoMillis();
String jtdate = "2010-01-01T12:00:00+01:00";
System.out.println(parser2.parseDateTime(jtdate));
或者更简单的说,通过构造函数使用默认解析器:
Or more simply, use the default parser via the constructor:
DateTime dt = new DateTime( "2010-01-01T12:00:00+01:00" ) ;
对我来说,这很棒。
推荐答案
不幸的是,时区格式可用于 SimpleDateFormat (Java 6及更早版本)不是 ISO 8601 符合SimpleDateFormat了解时区字符串,如GMT + 01:00或+0100,后者根据 RFC#822 。
Unfortunately, the time zone formats available to SimpleDateFormat (Java 6 and earlier) are not ISO 8601 compliant. SimpleDateFormat understands time zone strings like "GMT+01:00" or "+0100", the latter according to RFC # 822.
即使Java 7根据ISO 8601增加了对时区描述符的支持SimpleDateFormat仍然无法正确解析完整的日期字符串,因为它不支持可选部分。
Even if Java 7 added support for time zone descriptors according to ISO 8601, SimpleDateFormat is still not able to properly parse a complete date string, as it has no support for optional parts.
使用regexp重新格式化输入字符串当然是一种可能性,但是替换规则不像您的问题那么简单:
Reformatting your input string using regexp is certainly one possibility, but the replacement rules are not as simple as in your question:
- 某些时区不是全小时关闭 UTC ,因此字符串不一定以:00结尾。
- ISO8601仅允许要包含在时区中的小时数,所以+01相当于+01:00。
- ISO8601允许使用Z表示使用UTC而不是+00:00。
- Some time zones are not full hours off UTC, so the string does not necessarily end with ":00".
- ISO8601 allows only the number of hours to be included in the time zone, so "+01" is equivalent to "+01:00"
- ISO8601 allows the usage of "Z" to indicate UTC instead of "+00:00".
更简单的解决方案可能是在JAXB中使用数据类型转换器,因为JAXB必须能够根据XML Schema规范解析ISO8601日期字符串。 javax.xml.bind.DatatypeConverter.parseDateTime(2010-01-01T12:00:00Z)
将给你一个 Calendar
对象,你可以简单地使用getTime(),如果你需要一个 Date
对象。
The easier solution is possibly to use the data type converter in JAXB, since JAXB must be able to parse ISO8601 date string according to the XML Schema specification. javax.xml.bind.DatatypeConverter.parseDateTime("2010-01-01T12:00:00Z")
will give you a Calendar
object and you can simply use getTime() on it, if you need a Date
object.
您也许可以使用 Joda-Time ,但我不知道你为什么要打扰
You could probably use Joda-Time as well, but I don't know why you should bother with that.
这篇关于将符合ISO 8601的字符串转换为java.util.Date的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!