将XMLGregorianCalendar转换为java.sql.Timestamp

我正在尝试将XMLGregorianCalendar日期分配给java.sql.Timestamp var,就像这样……

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

有任何想法吗..? 谢谢!

我找到了答案:

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

TL;博士

尽量避免遗留日期时间类。 但如果递交了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类已取代了非常麻烦的旧日期时间类。

  • javax.xml.datatype.XMLGregorianCalendarjava.time.ZonedDateTime替换。
  • java.util.GregorianCalendarjava.time.ZonedDateTime取代。 请注意添加到旧类的新转换方法。
  • java.sql.Timestampjava.time.Instant替换,两者都表示UTC的java.time.Instant ,分辨率为纳秒。

避免使用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.time对象。 所以不需要再次触摸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类?

  • Java SE 8Java SE 9Java SE 10及更高版本
    • 内置。
    • 带有捆绑实现的标准Java API的一部分。
    • Java 9增加了一些小function和修复。
  • Java SE 6Java SE 7
    • 许多java.timefunction都被反向移植到ThreeTen-Backport中的 Java 6和7。
  • Android的
    • 更高版本的Android捆绑java.time类的实现。
    • 对于早期的Android(<26), ThreeTenABP项目采用ThreeTen-Backport (如上所述)。 请参见如何使用ThreeTenABP ….

ThreeTen-Extra项目使用其他类扩展了java.time。 该项目是未来可能添加到java.time的试验场。 您可以在这里找到一些有用的课程,如IntervalYearWeekYearQuarter等。