java.util.Date 到 XMLGregorianCalendar [英] java.util.Date to XMLGregorianCalendar

查看:32
本文介绍了java.util.Date 到 XMLGregorianCalendar的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

解决方案

我想退后一步,以现代的眼光看待这个 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.toStringSystem.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 时区设置,请将 zone 设置为 ZoneId.systemDefault().

如果我绝对需要一个 XMLGregorianCalendar 怎么办?

有更多方法可以将 Instant 转换为 XMLGregorianCalendar.我将介绍一对夫妇,每一个都有其优点和缺点.首先,就像 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

Pro:它很短,我认为它不会带来任何惊喜.缺点:对我来说,将瞬间格式化为字符串并解析回来是一种浪费.

 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 的答案.

链接

Isn't there a convenient way of getting from a java.util.Date to a XMLGregorianCalendar?

解决方案

I should like to take a step back and a modern look at this 10 years old question. The classes mentioned, Date and XMLGregorianCalendar, are old now. I challenge the use of them and offer alternatives.

  • Date was always poorly designed and is more than 20 years old. This is simple: don’t use it.
  • XMLGregorianCalendar is old too and has an old-fashioned design. As I understand it, it was used for producing dates and times in XML format for XML documents. Like 2009-05-07T19:05:45.678+02:00 or 2009-05-07T17:05:45.678Z. These formats agree well enough with ISO 8601 that the classes of java.time, the modern Java date and time API, can produce them, which we prefer.

No conversion necessary

For many (most?) purposes the modern replacement for a Date will be an Instant. An Instant is a point in time (just as a Date is).

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

An example output from this snippet:

2009-05-07T17:05:45.678Z

It’s the same as the latter of my example XMLGregorianCalendar strings above. As most of you know, it comes from Instant.toString being implicitly called by System.out.println. With java.time, in many cases we don’t need the conversions that in the old days we made between Date, Calendar, XMLGregorianCalendar and other classes (in some cases we do need conversions, though, I am showing you a couple in the next section).

Controlling the offset

Neither a Date nor in Instant has got a time zone nor a UTC offset. The previously accepted and still highest voted answer by Ben Noland uses the JVMs current default time zone for selecting the offset of the XMLGregorianCalendar. To include an offset in a modern object we use an OffsetDateTime. For example:

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

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

Again this conforms with XML format. If you want to use the current JVM time zone setting again, set zone to ZoneId.systemDefault().

What if I absolutely need an XMLGregorianCalendar?

There are more ways to convert Instant to XMLGregorianCalendar. I will present a couple, each with its pros and cons. First, just as an XMLGregorianCalendar produces a string like 2009-05-07T17:05:45.678Z, it can also be built from such a string:

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

2009-05-07T17:05:45.678Z

Pro: it’s short and I don’t think it gives any surprises. Con: To me it feels like a waste formatting the instant into a string and parsing it back.

    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: It’s the official conversion. Controlling the offset comes naturally. Con: It goes through more steps and is therefore longer.

What if we got a Date?

If you got an old-fashioned Date object from a legacy API that you cannot afford to change just now, convert it to Instant:

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

Output is the same as before:

2009-05-07T17:05:45.678Z

If you want to control the offset, convert further to an OffsetDateTime in the same way as above.

If you’ve got an old-fashioned Date and absolutely need an old-fashioned XMLGregorianCalendar, just use the answer by Ben Noland.

Links

这篇关于java.util.Date 到 XMLGregorianCalendar的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆