簡體   English   中英

將長字符串解析為LocalDate變量

[英]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.

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