简而言之
ZonedDateTime zdt =
myJavaSqlDate.toLocalDate()
.atStartOfDay( ZoneId.of( "America/Montreal" ) ) ;
详情
不要将旧的日期时间类与java.time混合使用。避免使用旧类。因此,您对java.util.Date
的调用没有帮助。
请注意,java.sql.Date
表示仅包含日期的值,没有时间和时区。不幸的是,它实际上确实有时间和时区,但我们应该忽略这些事实。这是一个设计不良的类的hack。只有在还没有支持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为您确定该时间。时间
00:00:00
并不总是一天的开始,因为存在夏令时(DST)等异常情况。处理这些异常情况需要您指定时区,因为每个时区都有其自己的异常规则。因此,应用
ZoneId
来获取
ZonedDateTime
对象。
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ld.atStartOfDay( z );
关于 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
和更多。
datetime
而不是实体时,spring-data在某些情况下仅将其转换为java.sql.Date
,即使hibernate允许持久化具有ZonedDateTime字段的实体。在这种情况下,我们并不是因为想要混合使用它们,而是除了返回实体的查询或完全放弃spring-data之外,没有其他选择。 - Sofia Paixão