java.util.Date 到 XMLGregorianCalendar

新手上路,请多包涵

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

原文由 mac 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 688
2 个回答

我想退后一步,以现代的眼光看待这个 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 的现代替代品将是 InstantInstant 是一个时间点(就像 Date 一样)。

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

此代码段的示例输出:

2009-05-07T17:05:45.678Z

它与我的示例的后者相同 XMLGregorianCalendar 上面的字符串。正如你们大多数人所知,它来自 Instant.toStringSystem.out.println 隐式调用。使用 java.time,在很多情况下我们不需要过去在 Date , Calendar , XMLGregorianCalendar 之间进行的转换(在某些情况下,我们确实需要转换,不过,我将在下一节中向您展示一些)。

控制偏移量

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

亲:它很短,我认为它不会带来任何惊喜。缺点:对我来说,将即时格式化为字符串并将其解析回来感觉很浪费。

     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 获得了一个老式的 Date 对象,而您现在无法承担更改的费用,请将其转换为 Instant

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

输出与之前相同:

2009-05-07T17:05:45.678Z

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

如果你有一个老式的 Date 并且绝对需要一个老式的 XMLGregorianCalendar ,只需使用 Ben Noland 的答案。

链接

原文由 Ole V.V. 发布,翻译遵循 CC BY-SA 4.0 许可协议

GregorianCalendar c = new GregorianCalendar();
c.setTime(yourDate);
XMLGregorianCalendar date2 = DatatypeFactory.newInstance().newXMLGregorianCalendar(c);

原文由 Ben Noland 发布,翻译遵循 CC BY-SA 2.5 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题