web-dev-qa-db-ja.com

java.util.Date to XMLGregorianCalendar

Java.util.DateからXMLGregorianCalendarに到達する便利な方法はありませんか?

561
mac
GregorianCalendar c = new GregorianCalendar();
c.setTime(yourDate);
XMLGregorianCalendar date2 = DatatypeFactory.newInstance().newXMLGregorianCalendar(c);
1011
Ben Noland

ここで結局逆の変換(XMLGregorianCalendarからDateへ)を探しているかもしれない人のために:

XMLGregorianCalendar xcal = <assume this is initialized>;
Java.util.Date dt = xcal.toGregorianCalendar().getTime();
202
Nuno Furtado

これはGregorianCalendarからXMLGregorianCalendarに変換するためのメソッドです。演習として、Java.util.DateからGregorianCalendarへの変換の部分は残します。

import Java.util.GregorianCalendar;

import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

public class DateTest {

   public static void main(final String[] args) throws Exception {
      GregorianCalendar gcal = new GregorianCalendar();
      XMLGregorianCalendar xgcal = DatatypeFactory.newInstance()
            .newXMLGregorianCalendar(gcal);
      System.out.println(xgcal);
   }

}

編集:スロー: - )

30
sasuke

Joda-Time libraryを使用した1行の例

XMLGregorianCalendar xgc = DatatypeFactory.newInstance().newXMLGregorianCalendar(new DateTime().toGregorianCalendar());

Nicolas Mommaerts /の彼のコメントから - 受け入れられた答え

22
Chris Knight

上記の答えが私の正確なニーズを満たしていなかったので、私は私が以下に私の解決策を追加すると思っただけで。私のXmlスキーマは単一のDateTimeフィールドではなく、別々のDate要素とTime要素を必要としました。上記で使用されている標準のXMLGregorianCalendarコンストラクタはDateTimeフィールドを生成します。

(Javaは0から月を数えるので)月に1を加えなければならないなど、ゴスカが2、3あることに注意してください。

GregorianCalendar cal = new GregorianCalendar();
cal.setTime(yourDate);
XMLGregorianCalendar xmlDate = DatatypeFactory.newInstance().newXMLGregorianCalendarDate(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH)+1, cal.get(Calendar.DAY_OF_MONTH), 0);
XMLGregorianCalendar xmlTime = DatatypeFactory.newInstance().newXMLGregorianCalendarTime(cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND), 0);
12
khylo

ここでの私のエンコーディングが正しいことを願っています; Dより速くするには、単にコンストラクタ呼び出しの代わりにGregorianCalendarの醜いgetInstance()呼び出しを使用します。

import Java.util.GregorianCalendar;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

public class DateTest {

   public static void main(final String[] args) throws Exception {
      // do not forget the type cast :/
      GregorianCalendar gcal = (GregorianCalendar) GregorianCalendar.getInstance();
      XMLGregorianCalendar xgcal = DatatypeFactory.newInstance()
            .newXMLGregorianCalendar(gcal);
      System.out.println(xgcal);
   }

}
10
Daniel K.

XmlをデコードまたはエンコードしてJAXBを使用していると仮定すると、dateTimeバインディングを完全に置き換えて、スキーマ内のすべての日付に `XMLGregorianCalendar '以外のものを使用することが可能です。

そのようにして、価値を提供する素晴らしいコードを書くことに時間を費やすことができる間、あなたはJAXBに反復的なことをさせることができます。

Jodatimeの例DateTime:(これをJava.util.Dateでも行うことができます - ただし、一定の制限はありますが、jodatimeが好きで、コードからコピーされるので動作します)

<jxb:globalBindings>
    <jxb:javaType name="org.joda.time.LocalDateTime" xmlType="xs:dateTime"
        parseMethod="test.util.JaxbConverter.parseDateTime"
        printMethod="se.seb.bis.test.util.JaxbConverter.printDateTime" />
    <jxb:javaType name="org.joda.time.LocalDate" xmlType="xs:date"
        parseMethod="test.util.JaxbConverter.parseDate"
        printMethod="test.util.JaxbConverter.printDate" />
    <jxb:javaType name="org.joda.time.LocalTime" xmlType="xs:time"
        parseMethod="test.util.JaxbConverter.parseTime"
        printMethod="test.util.JaxbConverter.printTime" />
    <jxb:serializable uid="2" />
</jxb:globalBindings>

そしてコンバータ:

public class JaxbConverter {
static final DateTimeFormatter dtf = ISODateTimeFormat.dateTimeNoMillis();
static final DateTimeFormatter df = ISODateTimeFormat.date();
static final DateTimeFormatter tf = ISODateTimeFormat.time();

public static LocalDateTime parseDateTime(String s) {
    try {
        if (StringUtils.trimToEmpty(s).isEmpty())
            return null;
        LocalDateTime r = dtf.parseLocalDateTime(s);
        return r;
    } catch (Exception e) {
        throw new IllegalArgumentException(e);
    }
}

public static String printDateTime(LocalDateTime d) {
    try {
        if (d == null)
            return null;
        return dtf.print(d);
    } catch (Exception e) {
        throw new IllegalArgumentException(e);
    }
}

public static LocalDate parseDate(String s) {
    try {
        if (StringUtils.trimToEmpty(s).isEmpty())
            return null;
        return df.parseLocalDate(s);
    } catch (Exception e) {
        throw new IllegalArgumentException(e);
    }
}

public static String printDate(LocalDate d) {
    try {
        if (d == null)
            return null;
        return df.print(d);
    } catch (Exception e) {
        throw new IllegalArgumentException(e);
    }
}

public static String printTime(LocalTime d) {
    try {
        if (d == null)
            return null;
        return tf.print(d);
    } catch (Exception e) {
        throw new IllegalArgumentException(e);
    }
}

public static LocalTime parseTime(String s) {
    try {
        if (StringUtils.trimToEmpty(s).isEmpty())
            return null;
        return df.parseLocalTime(s);
    } catch (Exception e) {
        throw new IllegalArgumentException(e);
    }
}

こちらを参照してください。 XmlGregorianCalendarをDateに置き換える方法

タイムゾーン+タイムスタンプに基づいてインスタントにマッピングするだけでよく、元のタイムゾーンが実際には関連していない場合は、Java.util.Dateもおそらく大丈夫です。

4
KarlP

私はこの10年前の質問について一歩後退して現代的な見方をするのが好きです。言及されているクラスDateXMLGregorianCalendarは現在古くなっています。私はそれらの使用に挑戦し、選択肢を提供します。

  • Dateは、いつもうまく設計されておらず、20歳以上です。これは簡単です。使用しないでください。
  • XMLGregorianCalendarも古く、古風なデザインです。私が理解しているように、それはXML文書のためにXMLフォーマットで日付と時刻を生成するために使われました。 2009-05-07T19:05:45.678+02:002009-05-07T17:05:45.678Zのように。これらのフォーマットはISO 8601と十分に一致しており、現代のJavaの日付と時刻のAPIであるJava.timeのクラスがそれらを生成することができます。

変換不要

多くの(ほとんどの場合)目的で、Dateの現代の置き換えはInstantになります。 Instantは(Dateがそうであるように)ある時点です。

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

このスニペットからの出力例:

2009-05-07T17:05:45.678Z

これは、上記のXMLGregorianCalendar文字列の例の後者と同じです。ご存じのように、それはInstant.toStringによって暗黙のうちに呼び出されるSystem.out.printlnから来ています。 Java.timeでは、多くの場合、私たちがDateCalendarXMLGregorianCalendarと他のクラスの間で行った変換を必要としません(ただし、場合によっては変換を必要とします)次のセクション)。

オフセットを制御する

DateInstantもタイムゾーンも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タイムゾーン設定をもう一度使用する場合は、zoneZoneId.systemDefault()に設定します。

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

InstantXMLGregorianCalendarに変換する方法は他にもあります。それぞれ長所と短所があるカップルを紹介します。まず、XMLGregorianCalendar2009-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

Pro:それは公式の転換です。オフセットを制御することは自然に起こります。コン:それはより多くのステップを経て、したがってより長くなります。

日付を取得した場合はどうなりますか?

今変更することができない古いAPIから昔のDateオブジェクトを手に入れた場合は、それをInstantに変換します。

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

出力は以前と同じです。

2009-05-07T17:05:45.678Z

オフセットを制御したい場合は、上記と同じ方法でさらにOffsetDateTimeに変換します。

あなたが昔ながらのDateを手に入れていて、絶対に昔ながらのXMLGregorianCalendarを必要としているのなら、Ben Nolandによる答えを使ってください。

リンク集

4
Ole V.V.

このコードをチェックしてください: -

/* Create Date Object */
Date date = new Date();
XMLGregorianCalendar xmlDate = null;
GregorianCalendar gc = new GregorianCalendar();

gc.setTime(date);

try{
    xmlDate = DatatypeFactory.newInstance().newXMLGregorianCalendar(gc);
}
catch(Exception e){
    e.printStackTrace();
}

System.out.println("XMLGregorianCalendar :- " + xmlDate);

あなたは完全な例を見ることができます ここ

0
Akash