tl;博士
ZonedDateTime zdt =
myJavaSqlDate.toLocalDate()
.atStartOfDay( ZoneId.of( "America/Montreal" ) ) ;
详情
不要将旧的日期时间类与 java.time 混合。避免旧课程。所以你打电话给java.util.Date 没有帮助。
知道java.sql.Date 表示仅日期值,没有时间和时区。不幸的是,它实际上确实有时间和时区,但我们应该忽略这些事实。这是一个设计不良的类黑客。仅当您还没有支持 JDBC 4.2 和 java.time 类型的 JDBC 驱动程序时才使用它。
因此,当您必须使用 java.sql.Date 时,将其值转换为 LocalDate。 LocalDate 类表示没有时间和时区的仅日期值。
要与 java.time 相互转换,请查看添加到旧类的新方法。
LocalDate ld = myJavaSqlDate.toLocalDate();
往另一个方向发展。
java.sql.Date myJavaSqlDate = java.sql.Date.valueOf( ld );
如果您的目标是从仅日期值中获取日期时间值,则需要指定时间。如果您想要一天中的第一刻,让 java.time 为您确定一天中的那个时间。由于夏令时 (DST) 等异常情况,时间00:00:00并不总是一天的开始。处理此类异常需要您指定时区,因为每个时区都有自己的异常规则。所以应用ZoneId 来获取ZonedDateTime 对象。
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ld.atStartOfDay( z );
关于java.time
java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.Date、Calendar 和 SimpleDateFormat。
Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。
要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。
您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。
从哪里获得 java.time 类?
ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如Interval、YearWeek、YearQuarter 和more。