java.util.Date 转换为 XMLGregorianCalendar

java.util.Date to XMLGregorianCalendar

提问人:mac 提问时间:5/8/2009 最后编辑:Anonymousmac 更新时间:2/9/2022 访问量:686252

问:

难道没有一种方便的方法可以从 java.util.Date 到 XMLGregorianCalendar?

Java XML 日期 xmlGregorianCalendar

评论

2赞 Basil Bourque 5/26/2019
仅供参考:这两个可怕的类在几年前就被 JSR 310 中定义的 java.time 类所取代。请参阅类,以及添加到旧类的新转换方法。Ole V.V.的回答中的详细信息ZonedDateTime

答:

1083赞 Ben Noland 5/8/2009 #1
GregorianCalendar c = new GregorianCalendar();
c.setTime(yourDate);
XMLGregorianCalendar date2 = DatatypeFactory.newInstance().newXMLGregorianCalendar(c);

评论

5赞 Martin 2/11/2013
将 getInstance() 保留为某个转换器类中的静态变量是保存的吗?我试图在 JavaDoc 中查找它,但找不到任何东西。有点不知道并发使用是否会有问题?
39赞 Nicolas Mommaerts 3/15/2013
如果你愿意使用JodaTime,你可以用一行来完成:DatatypeFactory.newInstance().newXMLGregorianCalendar(new DateTime().toGregorianCalendar())
4赞 Junchen Liu 2/19/2015
XMLGregorianCalendar date2 = DatatypeFactory.newInstance().newXMLGregorianCalendar(new GregorianCalendar(YYYY, MM, DD));
3赞 questionaire 6/3/2015
请注意,日历不是线程安全的,因此 GregorianCalender 也不是。另请参阅 stackoverflow.com/questions/12131324/...
0赞 Alex Vayda 6/27/2016
一行版本 - DatatypeFactory.newInstance().newXMLGregorianCalendar(new GregorianCalendar() {{ setTime(yourDate);
32赞 sasuke 5/8/2009 #2

这是将 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);
   }

}

编辑:懒洋洋的:-)

评论

7赞 ftrujillo 1/21/2015
这是将GregorianCalendar转换为XMLGregorianCalendar的解决方案,而不是问题中指示的内容
10赞 Daniel K. 9/21/2010 #3

我希望我在这里的编码是正确的;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);
   }

}

评论

14赞 kan 4/19/2012
-1 表示使用 .getInstance()。 等效于 。不能使它更快,因为它使用相同的,但在此之前,它还检查默认区域设置,并可以创建日语或Buddish日历,所以对于一些幸运的用户来说,这将是!GregorianCalendar.getInstance()Calendar.getInstance()Calendar.getInstance()new GregorianCalendar()ClassCastException
209赞 Nuno Furtado 1/4/2011 #4

对于那些可能最终在这里寻找相反的转换(从到)的人:XMLGregorianCalendarDate

XMLGregorianCalendar xcal = <assume this is initialized>;
java.util.Date dt = xcal.toGregorianCalendar().getTime();
13赞 khylo 3/16/2011 #5

只是以为我会在下面添加我的解决方案,因为上面的答案不能满足我的确切需求。我的 Xml 架构需要单独的 Date 和 Time 元素,而不是单个 DateTime 字段。上面使用的标准 XMLGregorianCalendar 构造函数将生成一个 DateTime 字段

请注意,有几个哥特卡,例如必须在月份中添加一个(因为 java 从 0 开始计算月份)。

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);
8赞 KarlP 4/22/2013 #6

假设您正在对 xml 进行解码或编码并使用 ,则可以完全替换 dateTime 绑定,并对架构中的每个日期使用“XMLGregorianCalendar”以外的其他内容。JAXB

这样一来,你就可以做重复的事情,同时你可以把时间花在编写提供价值的精彩代码上。JAXB

jodatime 示例:(使用 java.util.Date 执行此操作也可以 - 但有一定的限制。我更喜欢 jodatime,它是从我的代码中复制的,所以我知道它有效......DateTime

<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?

如果您乐于根据时区+时间戳映射到某个时刻,并且原始时区并不真正相关,那么可能也没问题。java.util.Date

23赞 Chris Knight 2/3/2014 #7

使用 Joda-Time 库的一行示例:

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

感谢 Nicolas Mommaerts 在接受的答案中的评论。

2赞 Akash 3/24/2017 #8

看看这个代码:-

/* 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赞 fingerprints 12/14/2017
我不认为这个答案有什么新意。也许您可以编辑以前的答案,而不是发布另一个几乎相同的答案。
1赞 Panadol Chong 6/22/2018
如何为 XMLGregorianCalendar 做一个 dateFormat?
71赞 Anonymous 5/26/2019 #9

我想退后一步,以现代的方式看待这个已有10年历史的问题。上面提到的类 和 ,现在已经很旧了。我挑战它们的使用并提供替代方案。DateXMLGregorianCalendar

  • Date总是设计得很差,已经有20多年的历史了。这很简单:不要使用它。
  • XMLGregorianCalendar也很旧,设计很老式。据我了解,它用于为 XML 文档生成 XML 格式的日期和时间。喜欢或 .这些格式与 ISO 8601 非常吻合,以至于现代 Java 日期和时间 API java.time 的类可以生成它们,这是我们更喜欢的。2009-05-07T19:05:45.678+02:002009-05-07T17:05:45.678Z

无需转换

对于许多(大多数?)目的,a 的现代替代品将是 .An 是一个时间点(就像 a 一样)。DateInstantInstantDate

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

此代码片段的示例输出:

2009-05-07T17:05:45.678Z

它与上面的示例字符串中的后者相同。正如你们大多数人所知,它来自被隐式调用。使用 java.time,在许多情况下,我们不需要过去在 、 和其他类之间进行的转换(在某些情况下,我们确实需要转换,不过,我在下一节中将向您展示几个转换)。XMLGregorianCalendarInstant.toStringSystem.out.printlnDateCalendarXMLGregorianCalendar

控制偏移量

a 和 in 都没有时区和 UTC 偏移量。Ben Noland 之前接受的、仍然得票最高的答案使用 JVM 的当前默认时区来选择 .为了在现代对象中包含偏移量,我们使用 .例如:DateInstantXMLGregorianCalendarOffsetDateTime

    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,该怎么办?

还有更多方法可以转换为 。我将介绍一对夫妇,每一种都有其优点和缺点。首先,就像 生成一个字符串一样,它也可以从这样的字符串中构建:InstantXMLGregorianCalendarXMLGregorianCalendar2009-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

优点:它很短,我不认为它会给人任何惊喜。缺点:对我来说,将即时格式化为字符串并解析它是一种浪费。

    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

优点:这是官方转换。控制偏移量是自然而然的。缺点:它经历了更多的步骤,因此更长。

如果我们有约会呢?

如果您从旧 API 中获得了一个您现在无法更改的老式对象,请将其转换为:DateInstant

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

输出与之前相同:

2009-05-07T17:05:45.678Z

如果要控制偏移量,请以与上述相同的方式进一步转换为 an。OffsetDateTime

如果你有一个老式的,绝对需要一个老式的,只需使用本·诺兰的答案。DateXMLGregorianCalendar

链接

评论

7赞 Nagh 10/15/2020
你的答案并不是对原始问题的真正回答。当您可以在传统代码和现代代码之间进行选择时,它既好又有趣。但是,如果你带着这个问题来到这里,你就没有选择权了。甚至您要转换的样本也是完全错误的,因为它在 java 7 及更低版本中不起作用。
2赞 Anonymous 10/15/2020
谢谢你,@Nagh,的批评,感谢。我承认我估计大多数用户都有选择。对于那些邪恶的老板强迫他们使用 Java 7 的人(许多或少数),我建议通过向后移植 ThreeTen 向后移植使用 java.time。当然,您也可以查看许多其他答案。我仍然认为使用 Java 8 或更高版本功能的代码是正确的,或者我在工作中编写的大多数代码都是完全错误的。你是对的:我更相信写出有用的答案(至少对某些人来说)而不是直接回答所提出的问题。
2赞 Nagh 10/15/2020
我更相信写出有用的答案(至少对某些人来说)而不是直接答案我同意这一点,但是有用的答案必须包括直接的答案才能真正有帮助。我仍然需要处理 Java 5 代码,所以请感受我的痛苦。
0赞 Anonymous 10/15/2020
我感受到你的痛苦,@Nagh。如果您有选择,您可以查看 Joda-Time 进行任何严肃的日期和时间工作,它也可以开箱即用地生成 ISO 8601。一年半前写这个答案时,我认为重复许多其他人已经给出的直接答案是没有意义的。如果它丢失了,我同意,那么我会包括它。
0赞 Enerccio 5/16/2021
日期仍然被大量使用。
-1赞 Orhan ERDOGAN 2/9/2022 #10

我的解决方案

public static XMLGregorianCalendar DateToXMLGregorianCalendar(Date date) {

    GregorianCalendar gregoriancalendar = new GregorianCalendar();
    gregoriancalendar.setTime(date);
    XMLGregorianCalendar xmlGregorianCalendar = new XMLGregorianCalendarImpl(gregoriancalendar);
    return xmlGregorianCalendar;
}