簡體   English   中英

在 Java 中解析 XML 日期時間的最佳方法是什么?

[英]What's the best way to parse an XML dateTime in Java?

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

是否有一個很好的開源庫可以使用,還是應該使用 SimpleDateFormat 或類似的方式推出自己的庫?

我想你想要來自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調用。)

StaxMan 是絕對正確的。 為了使用SimpleDateFormat,您需要關閉每個SimpleDateFormat 中的松散解析並迭代幾種SimpleDateFormat 格式,直到找到解析日期而不拋出異常的格式。 如果您保留松散的解析,您很容易在您並不真正想要一個匹配項時獲得匹配項,並且XSD:DateTime詞法空間在格式上留下了一些靈活性,SimpleDateFormat 無法在單個表達式中處理。

XML Schema 1.0 確實使用了 ISO 8601,Joda Time 按照 Jon Skeet 的建議實現了 ISO 8601,因此這是一個有效的選擇。

如果您想將其全部保留在本機 Java 包中,您還可以將XMLGregorianCalendarDatatypeFactory結合使用來解析和創建 XSD:Datetime 字符串。

請參閱 DatatypeFactory.newXMLGregorianCalendar 和 XMLGregorianCalendar.toXMLFormat

tl;博士

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

細節

其他答案是正確的,但現在已經過時了。 他們使用麻煩的舊類,現在已被 java.time 框架取代。

沒有“XML 日期時間”這樣的東西。 XML沒有定義文本以外的任何數據類型。

使用 java.time

輸入字符串恰好符合ISO 8601標准格式。 因此無需指定格式模式,因為 java.time 類在解析/生成字符串時默認使用 ISO 8601。

Instant

第二個輸入字符串以Z結尾,是Zulu縮寫,表示UTC

Instant類表示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.time框架內置於 Java 8 及更高版本中。 這些類取代了舊的麻煩的日期時間類,例如java.util.Date.Calendarjava.text.SimpleDateFormat

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

要了解更多信息,請參閱Oracle 教程 並在 Stack Overflow 上搜索許多示例和解釋。

多的java.time功能后移植到Java 6和7在ThreeTen-反向移植並且還適於的AndroidThreeTenABP

ThreeTen-Extra項目用額外的類擴展了 java.time。 該項目是未來可能添加到 java.time 的試驗場。 您可能會在此處找到一些有用的類,例如IntervalYearWeekYearQuarter等。

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

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

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

有 XmlDateTime 類。 只需執行 XMLDateTime.stringToDate(xmlDateTime)。

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

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

理想情況下,模式感知(或用作事物的基礎)的 XML 處理包應該為類型化內容提供訪問器。 我知道一個( http://woodstox.codehaus.org/ ),但它(還)不提供對日期/時間的訪問,只是提供更簡單的類型(數字、數組、QNames 等)。 有一個請求支持 javax.xml.datatype.XMLGregorianCalendar。

唉,沒有多少人這樣做。 但是,如果您正在使用特定的包(如 XOM 或 JDOM 等),在他們的用戶列表中詢問這個問題可能不是一個壞主意。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM