在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的一部分.
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));
    }
}
输出:
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调用询问它.)
StaxMan绝对正确.为了使用SimpleDateFormat,您需要在每个SimpleDateFormat中关闭松散解析并迭代几个SimpleDateFormat格式,直到找到解析日期而不抛出异常的格式.如果你打开松散解析,你很容易得到匹配,当你真的不想要一个,并且XSD:DateTime的词法空间在SimpleDateFormat无法在单个表达式中处理的格式留下一些灵活性.
XML Schema 1.0确实使用了ISO 8601,正如Jon Skeet所建议的那样,Joda Time实现了这是一个有效的选项.
如果要将其全部保存在本机Java包中,还可以将XMLGregorianCalendar与DatatypeFactory结合使用来解析和创建XSD:Datetime字符串.
请参阅DatatypeFactory.newXMLGregorianCalendar和XMLGregorianCalendar.toXMLFormat
Instant instant = Instant.parse( "2002-10-10T17:00:00Z" );
OffsetDateTime odt = OffsetDateTime.parse( "2002-10-10T12:00:00-05:00" );
其他答案是正确的,但现在已经过时了。他们使用麻烦的旧类,现在已被 java.time 框架取代。
没有“XML 日期时间”这样的东西。XML没有定义文本以外的任何数据类型。
输入字符串恰好符合ISO 8601标准格式。因此无需指定格式模式,因为 java.time 类在解析/生成字符串时默认使用 ISO 8601。
Instant第二个输入字符串以 a 结尾,是Z, 的缩写Zulu,表示UTC。
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. 永远不要使用 3-4 个字母的缩写,这些缩写不是真正的时区,不是标准化的,甚至不是唯一的(!)。
ZoneId zoneId = ZoneId.of( "America/Cancun" );
ZonedDateTime zdt = odt.atZone( zoneId );
该java.time框架是建立在Java 8和更高版本。这些类取代了旧的麻烦的日期时间类,例如java.util.Date, .Calendar, & java.text.SimpleDateFormat。
现在处于维护模式的Joda-Time项目建议迁移到 java.time。
要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。
多的java.time功能后移植到Java 6和7在ThreeTen-反向移植并且还适于的Android在ThreeTenABP。
该ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,如Interval,YearWeek,YearQuarter,等。