parser範例 - 在Java中解析XML dateTime的最佳方法是什麼?




(9)

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

我可以使用一個很好的開源庫,還是應該使用SimpleDateFormat或類似的?


Answers

嘿,我知道它有點晚了但人們在2015年搜索XML日期解析,在Java 7中你可以使用

javax.xml.datatype.DatatypeFactory

獲取Calendar對象

這就是我做的..

private Calendar mPublishDate;
DatatypeFactory dtf=DatatypeFactory.newInstance();
this.mPublishDate=dtf.newXMLGregorianCalendar(mPublishDate/*date time string extracted from xml*/).toGregorianCalendar();

在XML Beans v2中,它將是XmlDateTime.Factory.parse(dateTimeString) ,但這很尷尬,因為它需要一個帶有開始和結束標記的元素,如<mytime>2011-10-20T15:07:14.112-07:00</mytime>

一種更簡單的方法是調用(new org.apache.xmlbeans.GDate(dateTimeString)).getDate()


我想你想要來自Joda Time的 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調用詢問它。)


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格式的正確時區名稱 。 切勿使用不是真正時區的3-4字母縮寫,不是標準化的,甚至不是唯一的(!)。

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

關於java.time

java.time框架內置於Java 8及更高版本中。 這些類取代了舊的麻煩的日期時間類,如java.util.Date.Calendarjava.text.SimpleDateFormat

現在處於維護模式Joda-Time項目建議遷移到java.time。

要了解更多信息,請參閱Oracle教程 。 並蒐索以獲取許多示例和解釋。

大部分java.time功能都被反向移植到ThreeTen-Backport Java 6和7,並進一步適應了ThreeTenABP Android

ThreeTen-Extra項目使用其他類擴展了java.time。 該項目是未來可能添加到java.time的試驗場。 您可以在這裡找到一些有用的課程,如IntervalYearWeekYearQuarter等。


您還可以在javax.xml.datatype.DatatypeFactory使用newXMLGregorianCalendar ,它可以為您提供詳細控制,包括檢測是否指定了時區。


請參閱解析和格式化dateTime值 ,但是: - 它將“GMT”作為默認時區 - 如果存在尾隨的非可解析部分則不會抱怨 - 不考慮TimeZone在錯誤的“GMT +”上默認為“GMT” XXXX“


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



skaffman似乎在給出一個很好的答案。

另一種方法可能是使用像xmlstarlet( http://xmlstar.sourceforge.net/ )這樣的命令行實用程序格式化XML,然後格式化這兩個字符串,然後使用任何diff實用程序(庫)來區分生成的輸出文件。 我不知道當命名空間出現問題時這是否是一個好的解決方案。





java xml