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

44 java xml

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

是否有一个很好的开源库我可以使用,或者我应该使用SimpleDateFormat或类似的自行推出?

MB.*_*MB. 74

还有javax.xml.bind.DatatypeConverter #parseDateTime(String xsdDateTime),它是JDK的一部分.

  • 我发现这是最简单的方法,无需添加另一个库.谢谢! (3认同)
  • 升级到Java 11后立即停止工作,因为11中的包javax.xml.bind已从JDK / JRE中删除。 (2认同)

Jon*_*eet 40

我想你想ISODateTimeFormat.dateTimeNoMillis()约达时间.总的来说,我强烈建议您远离Java中的内置日期/日历类.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));
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

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
Run Code Online (Sandbox Code Playgroud)

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


Dav*_*eri 6

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

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

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

请参阅DatatypeFactory.newXMLGregorianCalendar和XMLGregorianCalendar.toXMLFormat


Bas*_*que 5

tl;博士

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

细节

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

没有“XML 日期时间”这样的东西。XML没有定义文本以外的任何数据类型。

使用 java.time

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

Instant

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

Instant级表示时间轴上的时刻UTC,分辨率为纳秒

String input = "2002-10-10T17:00:00Z":
Instant instant = Instant.parse( input );
Run Code Online (Sandbox Code Playgroud)

OffsetDateTime

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

String input = "2002-10-10T12:00:00-05:00" ;
OffsetDateTime odt = OffsetDateTime.parse( input );
Run Code Online (Sandbox Code Playgroud)

ZonedDateTime

如果您有一个特定的时区,而不仅仅是与 UTC 的偏移量,请应用它。

使用正确的时区名称,格式为continent/region. 永远不要使用 3-4 个字母的缩写,这些缩写不是真正的时区,不是标准化的,甚至不是唯一的(!)。

ZoneId zoneId = ZoneId.of( "America/Cancun" );
ZonedDateTime zdt = odt.atZone( zoneId );
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

关于 java.time

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

现在处于维护模式Joda-Time项目建议迁移到 java.time。

要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。

多的java.time功能后移植到Java 6和7在ThreeTen-反向移植并且还适于的AndroidThreeTenABP

ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,如IntervalYearWeekYearQuarter,等。