浪费时间
一个问题可能是 java.sql.Date 应该是……</p>
通过在与实例关联的特定时区将小时、分钟、秒和毫秒设置为零来实现“标准化”。
…根据文档。这意味着,日期时间的时间部分正在从您的 java.util.Date 或 Joda-Time DateTime 对象中清除。
无时区
正如Gilbert Le Blanc指出的正确答案,java.util.Date 和 java.sql.Date 在内部都没有时区的概念。它们存储自 Unix纪元以来的毫秒数。
这些类带来了一个讨厌的技巧:它们的toString
方法将您的 JVM 的默认时区应用于字符串的呈现。非常混乱。该Date
对象没有时区,但当显示为字符串时,您会看到时区。
如果您的 java.util.Date 对象包含自纪元(1970 年开始)以来的 1344902399000L 毫秒数,这意味着2012-08-13T23:59:59.000Z
在 UTC/GMT 中。但是,如果您的 JVM 认为自己在启用夏令时 (DST) 的法国,您将看到比 UTC/GMT 提前 2 小时:2012-08-14T01:59:59.000+02:00
在该类的糟糕字符串格式中描述。同一时刻在不同时区具有不同的月份含义(13 对 14),墙上的时钟已经过了午夜。
乔达救援时间
Joda-Time 2.4 库在这里可以提供帮助。将 java.sql.Date 或 java.util.Date 对象与UTC 时区对象一起传递给DateTime构造函数,以清楚地了解您正在努力使用的值。
java.util.Date date = new java.util.Date( 1390276603054L );
DateTime dateTimeUtc = new DateTime( date, DateTimeZone.UTC );
System.out.println( "dateTimeUtc: " + dateTimeUtc );
运行时……</p>
2014-01-21T03:56:43.054Z
将另一个方向从 Joda-Time 转换为 java.util.Date…</p>
java.util.Date date = myDateTime.toDate();
将另一个方向从 Joda-Time 转换为 java.sql.Date…</p>
java.sql.Date date = new java.sql.Date( myDateTime.getMillis() );
更新——java.time
Joda-Time 项目现在处于维护模式,团队建议迁移到 java.time 类。
的等价物java.util.Date
是Instant
。该类表示UTCInstant
时间线上的时刻,分辨率为纳秒(最多九 (9) 位小数)。
Instant instant = Instant.ofEpochMilli( 1390276603054L );
应用时区 ,ZoneId
来生成ZonedDateTime
类似于 ajava.util.Calendar
和 Joda-Time的 a DateTime
。
ZoneId z = ZoneId.of( "Europe/Kaliningrad" );
ZonedDateTime zdt = instant.atZone( z );
现在提取一个仅限日期的值,即 的日期部分ZonedDateTime
,作为LocalDate
. 该类LocalDate
表示没有时间和时区的仅日期值。假装的也是如此:仅日期LocalDate
值。java.sql.Date
LocalDate localDate = zdt.toLocalDate() ;
在 JDBC 4.2 及更高版本中,您可以通过PreparedStatement::setObject
和直接将 java.time 类型与兼容的驱动程序一起使用ResultSet::getObject
。
myPreparedStatement.setObject( … , localDate );
……和……</p>
LocalDate ld = myResultSet.getObject( … , LocalDate.class );
对于较旧的不兼容驱动程序,通过使用添加到旧java.sql.Date
类LocalDate
的新方法toLocalDate
和valueOf( LocalDate )
.