1. ホーム
  2. java

[解決済み] java.util.DateからXMLGregorianCalendarへの変換

2022-03-16 17:46:11

質問

java.util.Date から XMLGregorianCalendar を取得する便利な方法はないのでしょうか?

どのように解決するのですか?

この10年前の質問について、一歩下がって現代的に考えてみたいと思います。言及されているクラスは DateXMLGregorianCalendar はもう古い。私はこれらの使用に異議を唱え、代替手段を提案します。

  • Date はもともとデザインが悪く、20年以上前のものです。これは単純に、使うなということです。
  • XMLGregorianCalendar も古いし、デザインも古臭い。私の理解では、XML文書の日付や時刻をXML形式で出力するために使われていたようです。たとえば 2009-05-07T19:05:45.678+02:00 または 2009-05-07T17:05:45.678Z . これらのフォーマットはISO 8601と十分に一致しており、最新のJavaの日付と時刻のAPIであるjava.timeのクラスはこれらを生成することができるので、私たちはこれを好んでいます。

変換不要

多くの場合(ほとんど? DateInstant . 某 Instant はある時点のものです(ちょうど Date である)。

    Instant yourInstant = // ...
    System.out.println(yourInstant);

このスニペットの出力例です。

2009-05-07T17:05:45.678Z

私の例の後半と同じです XMLGregorianCalendar の文字列があります。ご存知の方も多いと思いますが、由来は Instant.toString が暗黙のうちに呼び出され System.out.println . java.timeでは、多くの場合、昔は必要だった Date , Calendar , XMLGregorianCalendar といったクラスがあります(場合によっては変換が必要なこともあります。)

オフセットの制御

どちらも Date の中にも Instant はタイムゾーンもUTCオフセットも持っていません。Ben Nolandによる、以前受け入れられ、現在も最も投票数の多い回答は、JVMの現在のデフォルトのタイムゾーンを使用して XMLGregorianCalendar . モダンなオブジェクトにオフセットを含めるためには OffsetDateTime . 例えば

    ZoneId zone = ZoneId.of("America/Asuncion");
    OffsetDateTime dateTime = yourInstant.atZone(zone).toOffsetDateTime();
    System.out.println(dateTime);

2009-05-07T13:05:45.678-04:00

ここでもXML形式に準拠しています。もし、現在のJVMのタイムゾーン設定を再び使用したい場合は、次のように設定します。 zone から ZoneId.systemDefault() .

XMLGregorianCalendarがどうしても必要な場合はどうすればよいですか?

を変換する方法は他にもあります。 Instant から XMLGregorianCalendar . それぞれ長所と短所があるので、2つほど紹介します。まず、ちょうど XMLGregorianCalendar のような文字列を生成します。 2009-05-07T17:05:45.678Z また、そのような文字列から構築することもできます。

    String dateTimeString = yourInstant.toString();
    XMLGregorianCalendar date2
            = DatatypeFactory.newInstance().newXMLGregorianCalendar(dateTimeString);
    System.out.println(date2);

2009-05-07T17:05:45.678Z

長所:短いので、サプライズを与えられないと思う。Con: 私には、インスタントが文字列にフォーマットされ、それをパースして戻ってくるのは無駄のように感じられる。

    ZonedDateTime dateTime = yourInstant.atZone(zone);
    GregorianCalendar c = GregorianCalendar.from(dateTime);
    XMLGregorianCalendar date2 = DatatypeFactory.newInstance().newXMLGregorianCalendar(c);
    System.out.println(date2);

2009-05-07T13:05:45.678-04:00

長所:正式な変換である。オフセットのコントロールが自然にできる。短所:手順が多いため、時間がかかる。

もし、Dateを取得したら?

もし、あなたが昔ながらの Date オブジェクトに変換してください。 Instant :

    Instant i = yourDate.toInstant();
    System.out.println(i);

出力は前回と同じです。

2009-05-07T17:05:45.678Z

オフセットを制御したい場合は、さらに変換して OffsetDateTime を、上記と同様に

もし、昔ながらの Date が必要であり、昔ながらの XMLGregorianCalendar ベン・ノーランド氏の回答はこちらです。

リンク