2016-08-19 21 views
4

- 私で発見未解析のテキストのLocalDateTimeを使用して次の文字列をPASEしようとしているが、私はいつもド解析対象外のテキストがエラーを見つけます:エラーjava.time.format.DateTimeParseException:解析できませんでした、インデックス10

Error java.time.format.DateTimeParseException: Text '2016-08-18 14:27:15.103+02' could not be parsed, unparsed text found at index 10 
ここ

は私の文字列です:convertDate: '2016年8月18日14:27:15.103 + 02'

そして、私のコード:私は推測

public static LocalDate conversorStringToLocalDateTime(String convertDate) throws ParseException { 
    LocalDate dateTime =LocalDate.parse(convertDate); 
    return dateTime; 
} 

があまりにもCではありませんomplicated、buy私はエラーを見ることができません。 String内が原因だろうか?

+0

日時の隙間と思います。それはスペースチャー、またはノンブロッキングスペースですか?あなたの文字列がある種のフォームから来た場合、それはスペースとは異なる文字かもしれません –

+0

それはPostgreデータベースから来ます –

答えて

2

TL; DR

OffsetDateTime odt = OffsetDateTime.parse ("2016-08-18 14:27:15.103+02" , DateTimeFormatter.ofPattern ("yyyy-MM-dd HH:mm:ss.SSSX")) ; 

詳細

Answer by greg-449は、溶液(日時値の日付のみのオブジェクトを使用して)問題について正しいがありません。

その答えは、不必要に離れoffset-from-UTCに関する貴重な情報をスローLocalDateTimeを使用しています。 A LocalDateTimeではありません。は、タイムライン上の特定の瞬間を表していますが、特定の時間帯に合わせることによって可能なモーメントについての漠然とした考えだけです。

は、「2時間前にUTC」を意味するoffset-from-UTCです。したがって、UTCでは、この同時瞬間の時刻は12時間で、あなたの14時間より2時間少なくなります。このは、タイムライン上の特定の瞬間を表しありません。このオフセットは、あなたがLocalDateTimeはなくOffsetDateTimeで捨てている貴重な情報です。

文字列の形式は、標準のISO 8601形式に近いSQL形式です。単にTと真ん中にSPACEを交換してください。 java.timeクラスはデフォルトでISO 8601フォーマットを使用しているため、フォーマットパターンを指定する必要はありません。

String input = "2016-08-18 14:27:15.103+02"; 
String inputModified = input.replace (" " , "T"); 

残念ながら、Java 8にはオフセット値を1時間に短縮するか、またはコロンを省略したオフセット値を解析するバグがあります。 Java 9では修正されました。しかしJava 8では、入力を調整する必要があります。

// Workaround for Java 8 where 2-digit offset fails parsing. Fixed in Java 9. 
int lengthOfAbbreviatedOffset = 3; 
if (inputModified.indexOf ("+") == (inputModified.length() - lengthOfAbbreviatedOffset)) { 
    // If third character from end is a PLUS SIGN, append ':00'. 
    inputModified = inputModified + ":00"; 
} 
if (inputModified.indexOf ("-") == (inputModified.length() - lengthOfAbbreviatedOffset)) { 
    // If third character from end is a PLUS SIGN, append ':00'. 
    inputModified = inputModified + ":00"; 
} 

今すぐ解析してください。

OffsetDateTime odt = OffsetDateTime.parse (inputModified); 

コンソールにダンプします。+02+02:00に変換した方法に注意してください。あるいは

System.out.println ("input: " + input + " | inputModified: " + inputModified + " | odt: " + odt); 

input: 2016-08-18 14:27:15.103+02 | inputModified: 2016-08-18T14:27:15.103+02:00 | odt: 2016-08-18T14:27:15.103+02:00

、フォーマットパターンを指定。オフセット解析のバグは、この書式設定パターンを使用するときには噛みません。 Postgresから

DateTimeFormatter f = DateTimeFormatter.ofPattern ("yyyy-MM-dd HH:mm:ss.SSSX"); 
    OffsetDateTime odt = OffsetDateTime.parse (input , f); 

データベース

来て、あなたは、日付時刻オブジェクトではなく文字列として値を取得する必要があります。

JDBCドライバがJDBC 4.2に準拠している場合は、ResultSet::getObjectと呼び出してInstantまたはOffsetDateTimeを取得できます。そうでない場合は、ResultSet::getTimestampに電話してjava.sql.Timestampを取得し、すぐにTimestampオブジェクトのtoInstantを呼び出してjava.timeに変換します。

ビジネスロジックにはjava.timeを使用してください。 java.sql型は、データベースとの交換のためにのみ短時間使用してください。

5

あなたのコードは日付と時刻ではなく、日付のみを解析するLocalDateを使用しているため、解析後にスペースが見つかるとエラーになります。

LocalDateTimeを使用する必要がありますが、LocalDateTime.parse(String)には、使用している形式ではないISO形式の日付が必要です。

つまり、あなたの入力文字列の形式を指定するDateTimeFormatterを使用する必要があります。ような何か:

DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSX"); 
LocalDateTime result = LocalDateTime.parse(convertDate, format); 
+0

はい!それはうまくいった!以前はLocalDateTimeを使ってみたことがありましたが、DateTimeFormatterでは問題ありませんでした。 Thanx :) –

関連する問題