将XMLGregorianCalendar转换为java.sql.Timestamp

16

我试图将一个XMLGregorianCalendar日期赋值给一个java.sql.Timestamp变量,就像这样...

var1.setTimeStamp(Timestamp.valueOf(var2.getXMLGregorianCalendar().toString()))

但是显然,这个方法不起作用,并抛出异常...

java.lang.IllegalArgumentException: 时间戳格式必须为yyyy-mm-dd hh:mm:ss[.fffffffff]

我也尝试了以下方法:

var1.setTimeStamp((Timestamp) var2.getXMLGregorianCalendar().getTime())

但是...

java.lang.ClassCastException: java.util.Date无法强制转换为java.sql.Timestamp

有什么想法吗...?谢谢!

2个回答

26

我找到了答案:

    Timestamp timestamp = new Timestamp(var2.getXMLGregorianCalendar().toGregorianCalendar().getTimeInMillis());
    var1.setTimeStamp(timestamp);

3

简而言之

尽量避免使用过时的日期时间类。但如果有一个javax.xml.datatype.XMLGregorianCalendar,请转换为现代的java.time.Instant类。不需要使用java.sql.Timestamp

myPreparedStatement.setObject( 
    … , 
    myXMLGregorianCalendar  // If forced to work with a `javax.xml.datatype.XMLGregorianCalendar` object rather than a modern java.time class…
    .toGregorianCalendar()  // …convert to a `java.util.GregorianCalendar`, and then…
    .toZonedDateTime()      // …convert to modern `java.time.ZonedDateTime` class.
    .toInstant()            // Adjust to UTC by extracting an `Instant` object.
)

JDBC 4.2 版本起,从数据库中检索数据。

Instant instant = myResultSet.getObject( … , Instant.class ) ;

java.time

值得注意的是,旧的日期时间类已被新的java.time类所取代。

避免使用XMLGregorianCalendar。但是如果必须与尚未更新为java.time类型的旧代码进行接口交互,则需要进行转换。作为中间步骤,可以将其转换为GregorianCalendar,如您问题中所见的代码。
java.util.GregorianCalendar gc = myXMLGregorianCalendar.toGregorianCalendar() ;

现在使用添加到旧的GregorianCalendar类中的新便捷转换方法,获取一个现代的java.time.ZonedDateTime对象。
ZonedDateTime zdt = gc.toZonedDateTime() ;  // Convert from legacy class to modern class.

从那个特定的时区调整到UTC。根据定义,提取一个始终在UTC的瞬间Instant对象。

Instant instant = zdt.toInstant() ;  // Adjust from some time zone to UTC.

自JDBC 4.2版本开始,我们可以直接将Java时间对象与数据库进行交换。因此再也不需要触碰java.sql.Timestamp了。

myPreparedStatement.setObject( … , instant ) ;

检索:

Instant instant = myResultSet.getObject( … , Instant.class ) ;

关于 java.time

java.time 框架内置于 Java 8 及以上版本。这些类替代了旧的 遗留 日期时间类,例如 java.util.DateCalendarSimpleDateFormat,使日期和时间处理更加简单。

Joda-Time 项目现在处于维护模式,建议迁移到java.time 类。

了解更多信息,请参见Oracle教程。并在 Stack Overflow 上搜索许多示例和解释。规范是JSR 310

您可以直接与数据库交换 java.time 对象。使用符合JDBC 4.2或更高版本的JDBC驱动程序。无需字符串,也不需要java.sql.*类。

如何获取 java.time 类?

ThreeTen-Extra项目通过添加额外的类扩展了java.time。该项目是java.time可能未来添加内容的试验场。您可能会在这里找到一些有用的类,例如IntervalYearWeekYearQuarter更多


1
请不要在多个问题中添加相同的答案。请回答最好的一个,并将其余的标记为重复。请参见是否可以在多个问题中添加重复的答案? - Machavity
3
我曾考虑将此问题和同作者的另一个问题标记为重复。但它们并不是重复的。这个问题仅仅是询问如何从XMLGregorianCalendar转换到java.sql.Timestamp类。另一个问题则涉及该过程中时区差异的问题。我的另一个回答提供了有关使用UTC来避免混淆的额外建议。我的其他答案省略了一些细节和评论,引用了这个答案以获取更多信息。 - Basil Bourque

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接