1. ホーム
  2. java

[解決済み] ISO 8601準拠のStringをjava.util.Dateに変換する。

2022-03-24 18:05:50

質問

を変換しようとしています。 ISO 8601 フォーマットされた文字列を java.util.Date .

パターンを発見 yyyy-MM-dd'T'HH:mm:ssZ をLocaleと一緒に使うとISO8601に準拠します(比較サンプル)。

しかし java.text.SimpleDateFormat という文字列を変換することができません。 2010-01-01T12:00:00+01:00 . まず、これを 2010-01-01T12:00:00+0100 コロンがない。

ということで、現在の解答は

SimpleDateFormat ISO8601DATEFORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.GERMANY);
String date = "2010-01-01T12:00:00+01:00".replaceAll("\\+0([0-9]){1}\\:00", "+0$100");
System.out.println(ISO8601DATEFORMAT.parse(date));

というのは明らかにおかしい。何か見落としているのか、それとももっと良い解決策があるのでしょうか?


回答

JuanZeさんのコメントのおかげで ジョダタイム マジックで、それはまた ここに記載されている .

つまり、解決策は

DateTimeFormatter parser2 = ISODateTimeFormat.dateTimeNoMillis();
String jtdate = "2010-01-01T12:00:00+01:00";
System.out.println(parser2.parseDateTime(jtdate));

あるいはもっと単純に、コンストラクタ経由でデフォルトのパーサーを使用します。

DateTime dt = new DateTime( "2010-01-01T12:00:00+01:00" ) ;

私にとって、これは素敵なことです。

解決方法は?

残念ながら、タイムゾーン形式は シンプルデートフォーマット (Java 6以前)は ISO 8601 に準拠しています。SimpleDateFormat は "GMT+01:00" や "+0100" のようなタイムゾーン文字列を理解しますが、後者については RFC # 822 .

Java 7 が ISO 8601 に従ったタイムゾーン記述子のサポートを追加したとしても、SimpleDateFormat はオプション部分をサポートしていないため、完全な日付文字列を適切にパースすることはできません。

正規表現を使って入力文字列を再フォーマットすることは確かに一つの可能性ですが、置換ルールはご質問のような単純なものではありません。

  • 一部のタイムゾーンは、完全な時差ではありません UTC そのため、文字列は必ずしも ":00" で終わるとは限りません。
  • ISO8601ではタイムゾーンに含めることができるのは時間数のみなので、"+01"は"+01:00"と同じです。
  • ISO8601では、UTCを示すために、"+00:00"の代わりに"Z"を使用することができます。

JAXBはXML Schema仕様に従ってISO8601の日付文字列をパースできなければならないので、より簡単な解決策はJAXBのデータ型コンバータを使うことでしょう。 javax.xml.bind.DatatypeConverter.parseDateTime("2010-01-01T12:00:00Z") を与えると Calendar オブジェクトが必要な場合は、単純にgetTime()を使用することができます。 Date オブジェクトを作成します。

を使うことができるだろう。 Joda-Time(ジョダタイム もそうですが、わざわざそんなことをする必要があるのかわかりません。