没有从java.util.Date到XMLGregorianCalendar的便捷方法吗?
发布于 2019-05-26 19:57:20
我想退后一步,用现代的眼光来看待这个10年前的问题。这里提到的类Date
和XMLGregorianCalendar
现在已经很旧了。我对它们的使用提出了质疑,并提供了替代方案。
Date
的设计一直很糟糕,已经有20多年的历史了。这很简单:不要使用it.XMLGregorianCalendar
,因为它太老了,设计也很老式。据我所知,它用于为XML文档生成XML格式的日期和时间。比如2009-05-07T19:05:45.678+02:00
或2009-05-07T17:05:45.678Z
。这些格式与ISO8601非常一致,以至于现代Java日期和时间API java.time的类可以生成它们,这是我们更喜欢的。不需要转换
对许多人来说(大多数?)目的Date
的现代替代品将是Instant
。Instant
是一个时间点(就像Date
一样)。
Instant yourInstant = // ...
System.out.println(yourInstant);
此代码段的输出示例如下:
2009-05-07T17:05:45.678Z
它与我上面的第二个示例XMLGregorianCalendar
字符串相同。正如大多数人所知道的,它来自System.out.println
隐式调用的Instant.toString
。使用java.time,在许多情况下,我们不需要过去在Date
、Calendar
、XMLGregorianCalendar
和其他类之间进行的转换(在某些情况下,我们确实需要转换,不过,我将在下一节向您展示几个转换)。
控制偏移量
Date
和Instant
都没有时区和时差。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
支持:这是官方的转换。控制偏移量是很自然的。缺点:它经历了更多的步骤,因此更长。
如果我们有个约会呢?
如果您从遗留应用程序接口获得了一个老式的Date
对象,但现在无法更改,请将其转换为Instant
Instant i = yourDate.toInstant();
System.out.println(i);
输出与之前相同:
2009-05-07T17:05:45.678Z
如果你想控制偏移量,可以使用与上面相同的方式进一步转换为OffsetDateTime
。
如果你有一个老式的Date
,并且绝对需要一个老式的XMLGregorianCalendar
,那就用本·诺兰的答案吧。
链接
上使用java.time.
发布于 2009-05-07 17:22:15
GregorianCalendar c = new GregorianCalendar();
c.setTime(yourDate);
XMLGregorianCalendar date2 = DatatypeFactory.newInstance().newXMLGregorianCalendar(c);
发布于 2011-01-04 23:03:51
对于那些可能最终在这里寻找相反转换(从XMLGregorianCalendar
到Date
)的人:
XMLGregorianCalendar xcal = <assume this is initialized>;
java.util.Date dt = xcal.toGregorianCalendar().getTime();
https://stackoverflow.com/questions/835889
复制相似问题