简而言之
尽量避免使用过时的日期时间类。但如果有一个javax.xml.datatype.XMLGregorianCalendar
,请转换为现代的java.time.Instant
类。不需要使用java.sql.Timestamp
。
myPreparedStatement.setObject(
… ,
myXMLGregorianCalendar
.toGregorianCalendar()
.toZonedDateTime()
.toInstant()
)
自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()
从那个特定的时区调整到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.Date
、Calendar
和 SimpleDateFormat
,使日期和时间处理更加简单。
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可能未来添加内容的试验场。您可能会在这里找到一些有用的类,例如Interval
、YearWeek
、YearQuarter
和更多。
XMLGregorianCalendar
转换到java.sql.Timestamp
类。另一个问题则涉及该过程中时区差异的问题。我的另一个回答提供了有关使用UTC来避免混淆的额外建议。我的其他答案省略了一些细节和评论,引用了这个答案以获取更多信息。 - Basil Bourque