ISO 8601準拠の文字列をjava.util.Dateに変換する 質問する

ISO 8601準拠の文字列をjava.util.Dateに変換する 質問する

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

yyyy-MM-dd'T'HH:mm:ssZロケールと一緒に使用すると、パターンは ISO8601 に準拠することがわかりました(サンプルを比較)。

しかし、 を使用するとjava.text.SimpleDateFormat、正しくフォーマットされた String を変換できません。まずコロンのない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" ) ;

私にとっては、これはいいことだ。

ベストアンサー1

残念ながら、利用可能なタイムゾーンの形式はシンプルな日付形式(Java 6以前)は8601 規格準拠しています。SimpleDateFormatは「GMT+01:00」や「+0100」などのタイムゾーン文字列を理解します。後者はRFC 822 参照

Java 7 で ISO 8601 に準拠したタイムゾーン記述子のサポートが追加されても、SimpleDateFormat はオプション部分をサポートしていないため、完全な日付文字列を適切に解析できません。

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

  • 一部のタイムゾーンでは1時間オフではないUTCしたがって、文字列は必ずしも「:00」で終わるわけではありません。
  • ISO8601では、タイムゾーンに含めることができるのは時間数のみであるため、「+01」は「+01:00」と同等です。
  • ISO8601 では、「+00:00」の代わりに「Z」を使用して UTC を示すことができます。

より簡単な解決策は、JAXB のデータ型コンバータを使用することです。これは、JAXB が XML スキーマ仕様に従って ISO8601 日付文字列を解析できる必要があるためです。オブジェクトjavax.xml.bind.DatatypeConverter.parseDateTime("2010-01-01T12:00:00Z")が提供されCalendar、オブジェクトが必要な場合は、そのオブジェクトに対して getTime() を使用するだけですDate

おそらくジョダタイムも同様ですが、なぜそれを気にする必要があるのか​​わかりません (2022 年更新。おそらく、javax.xml.bindAndroid のjavax.xmlパッケージからセクション全体が欠落しているためです)。

おすすめ記事