我想退后一步,以现代的眼光看待这个 10 年前的问题。提到的类Date 和XMLGregorianCalendar 现在已经过时了。我挑战它们的使用并提供替代方案。
-
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 类可以生成它们,这是我们更喜欢的。
无需转换
对于许多(大多数?)用途,Date 的现代替代品将是 Instant。 Instant 是一个时间点(就像 Date 一样)。
Instant yourInstant = // ...
System.out.println(yourInstant);
此 sn-p 的示例输出:
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。我将介绍一对夫妇,每一个都有其优点和缺点。首先,就像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
Pro:这是官方转换。控制偏移量自然而然。缺点:它经过更多步骤,因此更长。
如果我们有一个日期呢?
如果您从旧 API 中获得了一个老式的 Date 对象,而您现在无法更改,请将其转换为 Instant:
Instant i = yourDate.toInstant();
System.out.println(i);
输出和之前一样:
2009-05-07T17:05:45.678Z
如果您想控制偏移量,请以与上述相同的方式进一步转换为OffsetDateTime。
如果您有一个老式的 Date 并且绝对需要一个老式的 XMLGregorianCalendar,请使用 Ben Noland 的答案。
链接