2017-06-23 6 views
3

有効な日付はDateTimeFormatterです。1つのDateTimeFormater Java 8ですべてのゾーンオフセットを処理する方法

String date1 = "2017-06-20T17:25:28"; 
    String date2 = "2017-06-20T17:25:28.477777"; 
    String date3 = "2017-06-20T17:25:28.477777Z"; 
    String date4 = "2017-06-20T17:25:28.477777UTC"; 
    String date5 = "2017-06-20T17:25:28.477777-05"; 
    String date6 = "2017-06-20T17:25:28.477777+05"; 
    String date7 = "2017-06-20T17:25:28.477777+05:30"; 
    String date8 = "2017-06-20T17:25:28.477777-05:30"; 
    String date9 = "2017-06-20T17:25:28.477777+0530"; 
    String date10 = "2017-06-20T17:25:28.477777-0530"; 

私は、次の日付時刻フォーマッタを試してみましたが、これは最後の二つの日付(date9date10)で失敗しました。

private static final DateTimeFormatter DATE_TIME_FORMATTER = new DateTimeFormatterBuilder() 
    .appendPattern("yyyy-MM-dd'T'HH:mm:ss") 
    .appendFraction(ChronoField.MICRO_OF_SECOND, 0, 6, true) 
         .optionalStart().appendZoneId().optionalEnd() 
         .optionalStart().appendOffset("+HH", "+00").optionalEnd() 
         .optionalStart().appendOffset("+HH:mm", "+00:00").optionalEnd() 
         .optionalStart().appendOffset("+HHmm", "+0000").optionalEnd().toFormatter(); 

date1date8に細かい作業からすべての日付が、最後の二つの日付解析しようとしたとき、私はDateTimeParseExceptionを得る:

例外スレッド「メイン」java.time.format.DateTimeParseExceptionで:テキストを " 2017-06-20T17:25:28.477777 + 0530 'を解析できませんでした。未解析のテキストがインデックス29に見つかりました。

私は次のように使用しています。

LocalDateTime.parse(date1, DATE_TIME_FORMATTER); 

OffsetIdPrinterParserからのオフセットのための有効なパターン:

static final class OffsetIdPrinterParser implements DateTimePrinterParser { 
     static final String[] PATTERNS = new String[] { 
      "+HH", "+HHmm", "+HH:mm", "+HHMM", "+HH:MM", "+HHMMss", "+HH:MM:ss", "+HHMMSS", "+HH:MM:SS", 
     }; // order used in pattern builder 

私は私の最後の二つの日付が失敗する理由私は、有効なZoneOffsetパターンを使用していながら理解することはできませんよ。

答えて

2

別の方法は、[]で区切ら任意のセクションを使用することで、各offset patternsVVx):

DATE_TIME_FORMATTER = DateTimeFormatter 
         // pattern with optional sections: fraction of seconds and offsets 
         .ofPattern("yyyy-MM-dd'T'HH:mm:ss[.SSSSSS][VV][x][xx][xxx]"); 

[]の各対は1つのoptionalStartoptionalEnd部に相当します。このフィールドが存在しない場合を解析するために、大文字のS(秒の小数部)をオプションとして含める必要があります。

その他のパタ​​ーン(VVおよびx)は、必要なさまざまなオフセットに対応しています。 javadocから:

Pattern Count Equivalent builder methods 
------- ----- -------------------------- 
    VV  2  appendZoneId() 
    x  1  appendOffset("+HHmm","+00") 
    xx  2  appendOffset("+HHMM","+0000") 
    xxx  3  appendOffset("+HH:MM","+00:00") 

これはすべての入力日付に適用されます。


唯一の違いは、(それはオプションセクションのように、またはゼロ桁)appendFractionは0から任意の量を受け入れながら[.SSSSSS]は、画分の秒フィールドに正確 6桁を受け入れることです6桁です。まさにこれと同じ動作を取得するには、DateTimeFormatterBuilderを使用する必要があります。

DATE_TIME_FORMATTER = new DateTimeFormatterBuilder() 
    // date and time 
    .appendPattern("yyyy-MM-dd'T'HH:mm:ss") 
    // fraction of seconds, from 0 to 6 digits 
    .appendFraction(ChronoField.MICRO_OF_SECOND, 0, 6, true) 
    // optional offset patterns 
    .appendPattern("[VV][x][xx][xxx]") 
    .toFormatter(); 
5

単にあなたのオプションのセクションの順序を逆:

private static final DateTimeFormatter DATE_TIME_FORMATTER = new DateTimeFormatterBuilder() 
     .appendPattern("yyyy-MM-dd'T'HH:mm:ss") 
     .appendFraction(ChronoField.MICRO_OF_SECOND, 0, 6, true) 
     .optionalStart().appendZoneId().optionalEnd() 
     .optionalStart().appendOffset("+HHmm", "+0000").optionalEnd() 
     .optionalStart().appendOffset("+HH:mm", "+00:00").optionalEnd() 
     .optionalStart().appendOffset("+HH", "+00").optionalEnd() 
     .toFormatter(); 

これは、すべての10のサンプル日付時刻文字列を解析します。

なぜそれが動作するのかよく分かりません。私は今、+HHの前に+HHmmを試していると仮定します。最後の2つを解析せずに残す代わりに、4つの数字が4つの数字になるようにします。

+2

私は順序が重要と推測したことがないでしょう... – Eugene

+0

@Eugeneしかし、まだ我々は、Javaがこれを行う理由をすることを見つける必要があります。 –

+0

@Ole V.V.ありがとう、それは動作します –

関連する問題