現代の答えに貢献したいと思います。の使用はお勧めしないためSimpleDateFormat、これについては後で詳しく説明します。
java.time
OffsetDateTime dateTime = OffsetDateTime.now(ZoneId.of("Europe/Rome"));
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSxx");
String text = dateTime.format(formatter);
OffsetDateTime test = OffsetDateTime.parse(text, formatter);
これにより2018-02-07T17:51:21.087+0100、質問で求めていたものにかなり近い のような文字列が生成され、うまく解析されます。フォーマット パターン文字列を使用SSSすると、常に秒の小数点以下 3 桁が生成され、解析によって正確に 3 桁の小数点以下が必要になります。Sたとえば、 orを使用SSSSSSして 1 桁または 6 桁を取得できます。私の Java 9 ではOffsetDateTime.now()、精度が 6 桁 (マイクロ秒) であるため、それより少ない値を指定すると、書式設定の精度が失われます。
編集:下位互換性のために、次のものを使用することはできませんが、読んでいる人のために、明示的なフォーマッタなしでバリアントを提示したいと思います:
String text = dateTime.toString();
OffsetDateTime test = OffsetDateTime.parse(text);
生成される文字列の 2 つの違いは次のとおりです。
- 精度をレンダリングするために必要な数の小数 3 のグループを生成します。通常、Java 8 では 3 桁、Java 9 では 6 桁ですが、時折、ミリ秒単位のラウンド数に達し、小数点以下の桁数が少なくなります。0 から 9 までのすべての文字列を解析するため、解析に問題はありません。そして、元の
OffsetDateTimeオブジェクトの完全な精度を常に維持します。
- UTC からのオフセットは、コロンで表示されます (例: )
+01:00。
コードで何が問題になったのですか?
このSimpleDateFormatクラスは古くて面倒なことで知られているため、現時点で問題がなかったjava.timeとしても、上記のように、代わりに最新の Java 日付と時刻 API を使用することをお勧めします。
SimpleDateFormat古いフォーマッタと最新のフォーマッタの違いの 1 つDateTimeFormatterはS、最新のフォーマッタでは秒の端数をSimpleDateFormat意味しますが、ミリ秒を意味するため、3 以外の数値は意味がないことです。ただし、それ以外の番号は受け入れます。たとえば89、21.089 秒214だった場合や、質問のように 13.214 だった場合などです。前者は正しくありません。21.089 秒は としてレンダリングされまし21.89た。1 つしかない場合、3 桁のミリ秒が原因で解析が失敗したと強く信じていますS。私のJava 8および9では動作し21.89、21秒89ミリ秒として解析されるため、エラーは均一になります。
この動作は、Java 9 のドキュメントに次のように記載されています。解析では、隣接する 2 つのフィールドを分離する必要がない限り、パターン文字の数は無視されます。」</p>
リンク