[英]Parsing a long string to a LocalDate variable
最近,我需要使用一個字符串並將其轉換為Java中的LocalDate變量。 我知道這是可能且容易的,但是我沒有看到以下內容:
上下文:我正在使用exiftool通過Java Runtime Execution從圖像中提取元數據。 問題是exiftool提供了下一個字符串:
2019:02:28 11:37:47-06:00
這不是您的常規標准ISO格式(或者至少我認為不是)。 我不知道這是否使用任何已經實施的格式化標准。 因此,為了解決我的問題,我創建了用於手動解析的下一個代碼:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy:MM:dd HH:mm:ssZ", Locale.ENGLISH);
LocalDate date = LocalDate.parse(VAR_WITH_STR_TO_CONVERT, formatter);
我認為這是手動轉換的良好實現,但是此代碼生成了下一個異常:
> Text '2019:02:28 11:37:47-06:00' could not be parsed at index 19
at java.time.format.DateTimeFormatter.parseResolved0(Unknown Source)
at java.time.format.DateTimeFormatter.parse(Unknown Source)
at java.time.LocalDate.parse(Unknown Source)
我相信問題出在我提供的要轉換的格式字符串上,但是在檢查DateTimeFormatter文檔時,我認為我有正確的字符串。
yyyy:MM:dd HH:mm:ssZ
我沒有主意,有人知道這里的問題嗎?
TL; DR對於時區,請使用XXX
而不是Z
來解析-06:00
類的值。
文檔,即DateTimeFormatter
的javadoc,指定:
偏移X和x:這將根據圖案字母的數量設置偏移格式。
- 除非分鍾非零,否則一個字母僅輸出小時,例如“ +01”,在這種情況下,分鍾也會輸出,例如“ +0130”。
- 兩個字母輸出小時和分鍾,不帶冒號,例如'+0130'。
- 三個字母輸出小時和分鍾,並帶有冒號,例如“ +01:30”。
- 四個字母輸出小時和分鍾,可選秒,不帶冒號,例如'+013015'。
- 五個字母輸出小時和分鍾,可選秒,並帶有冒號,例如“ +01:30:15”。
- 六個或更多字母會引發IllegalArgumentException。
當要輸出的偏移量為零時,模式字母“ X”(大寫)將輸出“ Z”,而模式字母“ x”(小寫)將輸出“ +00”,“ + 0000”或“ +00” :00' 。
偏移Z:根據格式字母的數量設置偏移格式。
- 一個,兩個或三個字母輸出小時和分鍾,不帶冒號,例如“ +0130”。 當偏移量為零時,輸出為“ +0000”。
- 四個字母輸出完整形式的本地化偏移量,等同於四個字母的Offset-O。 如果偏移量為零,則輸出將是相應的本地化偏移量文本。
- 五個字母輸出小時,分鍾,如果非零,則可選秒,帶冒號。 如果偏移為零,則輸出“ Z”。
- 六個或更多字母會引發IllegalArgumentException。
如您所見,您使用了1 Z
,表示-0600
。
要使用冒號來解析帶有小時和分鍾(可選秒)的時區,您需要突出顯示的模式之一:
XXX UTC is `Z`.
XXXXX UTC is `Z`. Optional seconds.
xxx UTC is `+00:00`
xxxxx UTC is `+00:00`. Optional seconds.
ZZZZZ UTC is `Z`. Optional seconds.
2019:02:28 11:37:47-06:00
這不是您的標准ISO格式
類似於ISO 8601:
T
字符替換中間的SPACE字符。 您可以通過在SPACE上拆分字符串,替換第一部分中的前兩個冒號,然后將其縫合在一起來實現。
String input = "2019:02:28 11:37:47-06:00";
String[] parts = input.split(" ");
String inputModified = parts[0].replace( ":" , "-" ) + "T" + parts[1] ;
xxxxx
或者,您可以使用DateTimeFormatter
對象定義自定義格式設置模式。 使用五個x
代碼字符,以小時和分鍾的偏移量(帶COLON字符定界符)為單位。
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu:MM:dd HH:mm:ssxxxxx") ;
在IdeOne.com上實時運行的代碼中請參見此格式化程序 。
OffsetDateTime
LocalDate.parse
不,首先解析所有內容,而不僅是日期部分,以防萬一您可能覺得有價值。 解析為OffsetDateTime
因為您的輸入表示相對於UTC的偏移量(小時-分鍾-秒),而不是完整的時區( Continent/Region
)。
OffsetDateTime odt = OffsetDateTime.parse( input ) ;
顯然,您只需要日期部分,而不需要時間和UTC偏移量。 假設您希望在該偏移量中看到日期,只需調用toLocalDate
。
LocalDate ld = odt.toLocalDate() ;
ld.toString():2019-02-28
或者,也許您想要在其他地方看到的日期。 請記住,對於任何給定的時刻,日期和時間在全球各地都會隨時區而變化。 在Asia/Japan
可能是“明天”,而在America/Edmonton
可能是“昨天”。
如果您希望使用UTC中顯示的日期:
OffsetDateTime odtUtc = odt.withOffsetSameInstant( ZoneOffset.UTC ) ;
LocalDate ld = odtUTc.toLocalDate() ;
ZonedDateTime
或者,也許您想要某個特定時區中顯示的日期。
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
LocalDate ld = zdt.toLocalDate() ;
提示:如果您可以在日期部分確定冒號的來源,請向他們介紹ISO 8601標准。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.