在Java中解析XML dateTime的最佳方法是什么?

时间:2009-05-26 05:12:39

标签: java xml

在Java中解析XML dateTime的最佳方法是什么?法定日期时间值包括2002-10-10T12:00:00-05:00和2002-10-10T17:00:00Z

我可以使用一个好的开源库,还是应该使用SimpleDateFormat或类似的?

9 个答案:

答案 0 :(得分:72)

答案 1 :(得分:39)

我想你想要来自ISODateTimeFormat.dateTimeNoMillis()Joda Time。一般来说  我强烈敦促你远离Java中的内置Date / Calendar类。 Joda Time的设计要好得多,有利于不变性(特别是格式化程序是不可变的和线程安全的),并且是Java 7中新的日期/时间API的基础。

示例代码:

import org.joda.time.*;
import org.joda.time.format.*;

class Test
{   
    public static void main(String[] args)
    {
        parse("2002-10-10T12:00:00-05:00");
        parse("2002-10-10T17:00:00Z");
    }

    private static final DateTimeFormatter XML_DATE_TIME_FORMAT =
        ISODateTimeFormat.dateTimeNoMillis();

    private static final DateTimeFormatter CHECKING_FORMAT =
        ISODateTimeFormat.dateTime().withZone(DateTimeZone.UTC);

    static void parse(String text)
    {
        System.out.println("Parsing: " + text);
        DateTime dt = XML_DATE_TIME_FORMAT.parseDateTime(text);
        System.out.println("Parsed to: " + CHECKING_FORMAT.print(dt));
    }
}

输出:

Parsing: 2002-10-10T12:00:00-05:00
Parsed to: 2002-10-10T17:00:00.000Z
Parsing: 2002-10-10T17:00:00Z
Parsed to: 2002-10-10T17:00:00.000Z

(请注意,在输出中两者都以相同的UTC时间结束。格式化的输出使用UTC,因为我们通过withZone调用询问它。)

答案 2 :(得分:6)

StaxMan绝对正确。为了使用SimpleDateFormat,您需要在每个SimpleDateFormat中关闭松散解析并迭代几个SimpleDateFormat格式,直到找到解析日期而不抛出异常的格式。如果你打开松散解析,你很容易得到匹配,当你真的不想要一个,而lexical space of XSD:DateTime在SimpleDateFormat无法在单个表达式中处理的格式留下一些灵活性。

XML Schema 1.0确实使用了ISO 8601,正如Jon Skeet所建议的那样,Joda Time实现了这是一个有效的选项。

如果要将其全部保存在本机Java包中,还可以将XMLGregorianCalendarDatatypeFactory结合使用来解析和创建XSD:Datetime字符串。

请参阅DatatypeFactory.newXMLGregorianCalendar和XMLGregorianCalendar.toXMLFormat

答案 3 :(得分:2)

Parse and format dateTime values,但是: - 它将“GMT”作为默认时区 - 如果有不可解析的部分,则不会抱怨 - 没有考虑到TimeZone在错误的“GMT + xxxx”上默认为“GMT”

答案 4 :(得分:2)

TL;博士

Instant instant = Instant.parse( "2002-10-10T17:00:00Z" );
OffsetDateTime odt = OffsetDateTime.parse( "2002-10-10T12:00:00-05:00" );

详细

其他答案是正确的,但现在已经过时了。他们使用现在由java.time框架取代的麻烦的旧类。

没有“XML dateTime”这样的东西。 XML未定义文本之外的任何数据类型。

使用java.time

输入字符串恰好符合ISO 8601标准格式。所以不需要指定格式化模式,因为java.time类在解析/生成字符串时默认使用ISO 8601。

Instant

第二个输入字符串以Z结尾,Zulu的缩写,表示UTC

Instant类代表UTC中时间轴上的一个时刻,分辨率为nanoseconds

String input = "2002-10-10T17:00:00Z":
Instant instant = Instant.parse( input );

OffsetDateTime

第一个输入字符串包含UTC的偏移量,因此我们将其解析为OffsetDateTime

String input = "2002-10-10T12:00:00-05:00" ;
OffsetDateTime odt = OffsetDateTime.parse( input );

ZonedDateTime

如果你有一个特定的时区,而不是仅仅偏离UTC,请应用它。

continent/region的格式使用proper time zone name。切勿使用不是真正时区的3-4字母缩写,不是标准化的,甚至不是唯一的(!)。

ZoneId zoneId = ZoneId.of( "America/Cancun" );
ZonedDateTime zdt = odt.atZone( zoneId );

关于java.time

java.time框架内置于Java 8及更高版本中。这些类取代了旧的麻烦日期时间类,例如java.util.Date.Calendar和& java.text.SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。

大部分java.time功能都被反向移植到Java 6& ThreeTen-Backport中的7,并进一步适应Android中的ThreeTenABP

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuarter等。

答案 5 :(得分:1)

http://xmlbeans.apache.org/samples/DateTime.html

有XmlDateTime类。只需执行XMLDateTime.stringToDate(xmlDateTime)。

答案 6 :(得分:1)

在XML Beans v2中它将是XmlDateTime.Factory.parse(dateTimeString),但这很尴尬,因为它需要一个带有开始和结束标记的元素,如<mytime>2011-10-20T15:07:14.112-07:00</mytime>

更简单的方法是致电(new org.apache.xmlbeans.GDate(dateTimeString)).getDate()

答案 7 :(得分:1)

您还可以在javax.xml.datatype.DatatypeFactory中使用newXMLGregorianCalendar,它可以为您提供详细的控制,包括检测是否指定了时区。

答案 8 :(得分:0)

理想情况下,支持模式(或用作事物基础)的XML处理包应该为类型化内容提供访问器。我知道一个(http://woodstox.codehaus.org/),但它(尚未)提供对日期/时间的访问,只是更简单的类型(数字,数组,QNames等)。请求支持javax.xml.datatype.XMLGregorianCalendar。

唉,没有多少人这样做。但是,如果您使用的是特定包(如XOM或JDOM等),在用户列表中提出此问题可能不是一个坏主意。