我正在尝试使用JDBC将java.util.Date
从应用程序保存到我的SQL Server数据库。
当我使用下面的方法将java.util.Date
转换为java.sql.Date
时,会截断时间部分。
java.sql.Date javaSqlExpiryDate = new java.sql.Date(javaUtilExpiryDate.getTime());
System.out.println("javaUtilExpiryDate: " + javaUtilExpiryDate.toString());
System.out.println("javaSqlExpiryDate: " + javaSqlExpiryDate.toString());
控制台窗口将输出报告为:
javaUtilExpiryDate:Thu Sep 01 18:19:08 IST 2016
javaSqlExpiryDate:2016-09-01
如何保留时间部分?
答案 0 :(得分:6)
是的,这是预期的和记录在案的行为。
为了符合SQL DATE的定义,java.sql.Date实例包含的毫秒值必须通过在特定时区中将小时,分钟,秒和毫秒设置为零来“标准化”。实例是关联的。
如果您想保留时间,则需要使用java.sql.Timestamp
(特别是如果数据库中的列定义为datetime
)。
答案 1 :(得分:0)
只需将导入从java.sql.Date
更改为java.sql.Timestamp
答案 2 :(得分:0)
myPreparedObject.setObject(
1 ,
myJavaUtilDate.toInstant() // Convert legacy object to modern java.time object, `Instant`.
)
其他答案是正确的。 java.util.Date
类表示日期和以UTC表示的时间。 java.sql.Date
仅代表日期,没有时间。好吧,实际上,java.sql.Date
假装只代表一个日期,但实际上,作为一个设计糟糕的黑客,它是java.util.Date
类的子类,因此确实有一个时间 - 天。混乱?是。避免这些可怕的旧遗留类的众多原因之一。
现在我们有了一个更好的方法,即java.time类。
在过去,您会将java.util.Date
对象转换为java.sql.Timestamp
。
现在,使用JDBC driver支持JDBC 4.2及更高版本,您可以将java.time对象直接发送到数据库或从数据库发送。不需要java.util和java.sql类,只需坚持使用java.time类。
如果您必须使用java.util.Date
与旧代码交互,请使用添加到旧类中的新方法转换为java.time.Instant
。
Instant
类代表UTC中时间轴上的一个时刻,分辨率为nanoseconds(小数部分最多九(9)位)。
Instant instant = myJavaUtilDate.toInstant() ;
通过Instant
和PreparedStatement::setObject
与数据库交换ResultSet::getObject
。
myPreparedStatement.setObject( … , instant ) ;
和...
Instant instant = myResultSet.getObject( … , Instant.class ) ;
要通过UTC以外的其他时区查看此时刻,请应用ZoneId
获取ZonedDateTime
。
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和& SimpleDateFormat
现在位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
从哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
和more。