2017-03-27 20 views
2

我有解析以下日期格式問題:DateTimeFormatter無法解析由自身產生串

2017-03-27T08:27:43.326TGMT-05:00 

我有代碼,其中DateTimeFormatter產生串出的ZonedDateTime,並作爲下一步我試圖再次解析字符串,創建ZonedDateTime實例,但是如我所料不工作:

String pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'T'ZZZZ"; 
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern); 
String dateStr = ZonedDateTime.now().format(formatter); 

System.out.println(dateStr); 

ZonedDateTime dateParsed = ZonedDateTime.parse(dateStr, formatter); 
System.out.println(dateParsed); 

上面的代碼產生:

2017-03-27T08:27:43.326TGMT-05:00 
java.time.format.DateTimeParseException: Text '2017-03-27T08:27:43.326TGMT-05:00' could not be parsed: String index out of range: 33 

    at java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1920) 
    at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1855) 

尋找任何見解如何拿出工作模式,它能夠創造ZonedDateTime實例出來的2017-03-27T08:27:43.326TGMT-05:00

+1

改變你的模式爲:'String pattern =「yyyy-MM-dd'T'HH:mm:ss.SSS'T'ZZZZZ」;'(一個Z更多),它的工作原理 – Jens

+0

似乎也適用於剛三個Zs。 –

+1

@BrianClapper,但是三個Z會導致輸出與OP有'.512T-0500'而不是'.512TGMT-05:00' –

回答

2

貪圖明白什麼是錯的我一起來看看DateTimeFormatterBuilder.java:3563源代碼,其中的例外是上調。

我看到有一段代碼可以解析GMT-05:00之後的秒部分。

所以,如果你添加秒情況下它只會工作...

ZonedDateTime dateParsed = ZonedDateTime.parse(dateStr+":00", formatter); 
+0

謝謝,它是這樣工作的,但這仍然是奇怪的情況,我想嘗試找出更好的解決方案 – endryha

0

要了解ZZZZ模式做什麼,看看在JDK docs,在那裏你可以看到它的含義:

Pattern Count Equivalent builder methods 
------- ----- -------------------------- 
ZZZZ  4  appendLocalizedOffset(TextStyle.FULL); 

因此,ZZZZ相當於appendLocalizedOffset(TextStyle.FULL)。如果你看看appendLocalizedOffset方法:

追加局部區域偏移,如'GMT + 01:00',到格式化。 這追加一個局部區域偏移建設者,是由指定的樣式控制,以這種方法本地化偏移格式:

  • - 格式的本地化偏移的文字,如「GMT, 2位小時和分鐘字段,可選的第二字段,如果非零和冒號。

並注意它解析和格式化時具有不同的行爲:

格式化,偏移是用一機構相當於獲得查詢的時間與TemporalQueries.offset()。如果無法獲得偏移量,則除非格式化程序的部分是可選的,否則將引發異常。

解析期間,使用上面定義的格式解析偏移量。如果無法解析偏移量,則除非格式器的部分是可選的,否則將引發異常。

所以,似乎ZZZZ模式格式化時(不秒的時候,它是零)增加了GMT-05:00,但在解析時,它會嘗試解析秒(即使他們不存在)。 這就是爲什麼在解析時,最後需要添加:00(因爲@freedev確實是in his answer)。

至於ZZZZ似乎是增加了GMT前偏移(所有其他人只是不添加的GMT偏移)唯一的模式,我認爲唯一的解決辦法是通過手工添加它。您可以使用java.time.format.DateTimeFormatterBuilder類它:

DateTimeFormatter formatter = new DateTimeFormatterBuilder() 
    // append the yyyy-MM-dd'T'HH:mm:ss.SSS pattern 
    .appendPattern("yyyy-MM-dd'T'HH:mm:ss.SSS") 
    // append "T" and "GMT" 
    .appendLiteral("TGMT") 
    // append the offset (-05:00) 
    .appendOffsetId() 
    .toFormatter(); 

有了這個格式,您的代碼將如預期:

String dateStr = ZonedDateTime.now().format(formatter); 
System.out.println(dateStr); 

ZonedDateTime dateParsed = ZonedDateTime.parse(dateStr, formatter); 
System.out.println(dateParsed); 

輸出:

2017-05-25T08:42:17.799 TGMT-05:00

2017-05-25T08:42:17.799-05:00


測試您的輸入:

String input = "2017-03-27T08:27:43.326TGMT-05:00"; 
System.out.println(input); 
System.out.println(ZonedDateTime.parse(input, formatter)); 

輸出:

2017-03-27T08:27:43.326TGMT-05:00

2017-03-27T08 :27:43.326-05:00


PS:在類似案例,我更喜歡使用DateTimeFormatterBuilder,但你可以做的使用DateTimeFormatter.ofPattern直接同:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'TGMT'xxx"); 

這工作方式完全相同。

相關問題