如果我在一个恰好是java.sql.Date的变量上使用java.util.Date的toInstant(),我会得到一个UnsupportedOperationException.try {java.util.Date input = new java.sql.Date(System.currentTimeMillis());LocalDate dat...

如果我在一个恰好是java.sql.Date的变量上使用java.util.Date的toInstant(),我会得到一个UnsupportedOperationException.
try {
java.util.Date input = new java.sql.Date(System.currentTimeMillis());
LocalDate date = input.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
} catch (UnsupportedOperationException e) {
// grrr!
}
我关心的java.util.Date来自mysql DB中的DATE字段,通过遗留API,实际上是java.sql.Date.
现在以下相关问题都非常有趣:
UnsupportedOperationException – Why can’t you call toInstant() on a java.sql.Date?
Convert java.util.Date to java.time.LocalDate
LocalDate to java.util.Date and vice versa simplest conversion?
但它们没有提供任何截断java.util.Date的优雅方法来摆脱时间组件并获得Java 8 LocalDate.
我承认存在一个问题,即一个时区中的同一时刻可能与另一个时区的同一时刻不同.
我怀疑解决方案将涉及java.util.Calendar,而不是制定我自己的解决方案,我宁愿建立别人先做的事情.
我宁愿找到比这更短的东西:
from 07003 :
06001
解决方法:
如果已知输入变量是java.sql.Date,那么您可以简单地转换它并调用toLocalDate()方法:
LocalDate date = ((java.sql.Date) input).toLocalDate();
不幸的是,你不能在java.sql.Date上调用toInstant(),因为according to javadoc,它总是抛出UnsupportedOperationException.
如果您不知道类型(可以是java.util.Date或java.sql.Date),您可以使用getTime()方法返回的值来构建Instant,然后将其转换为时区(下面我使用的是JVM的默认值),最后从中获取本地日期:
LocalDate date = Instant
// get the millis value to build the Instant
.ofEpochMilli(input.getTime())
// convert to JVM default timezone
.atZone(ZoneId.systemDefault())
// convert to LocalDate
.toLocalDate();
toLocalDate()方法获取日期部分(日/月/年),忽略其余部分,因此无需截断它:如果时间是午夜,上午10点或当天的任何其他时间都无关紧要,toLocalDate()将忽略它并获得日期部分.
但是,如果您真的想将时间设置为午夜,则可以使用with method并将LocalTime传递给它:
LocalDate date = Instant
// get the millis value to build the Instant
.ofEpochMilli(input.getTime())
// convert to JVM default timezone
.atZone(ZoneId.systemDefault())
// set time to midnight
.with(LocalTime.MIDNIGHT)
// convert to LocalDate
.toLocalDate();
但正如我所说,toLocalDate()方法将忽略时间部分,因此在这种情况下不需要设置时间(LocalDate将是相同的).
您还可以检查日期的类型并相应地选择相应的操作,如下所示:
if (input instanceof java.sql.Date) {
date = ((java.sql.Date) input).toLocalDate();
} else {
date = input.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
}
您可以根据需要使用任何其他时区,而不是使用JVM默认时区(ZoneId.systemDefault()),通过调用ZoneId.of(“zoneName”),其中区域名称是任何有效的IANA timezones names(始终格式为Region / City,如America / New_York或Europe / London).
避免使用3个字母的缩写(如CET或PST),因为它们是ambiguous and not standard.
您可以通过调用ZoneId.getAvailableZoneIds()获取可用时区列表(并选择最适合您系统的时区).如果需要,您还可以继续使用JVM默认时区,但要提醒它为can be changed without notice, even at runtime,因此最好始终明确指出您正在使用的时区.
本文标题为:在没有* toInstant()的情况下将java.util.Date截断为LocalDate *,因为java.sql.Date给出了UnsupportedOperationException


基础教程推荐
- Java正则表达式API边界匹配 2022-12-19
- 一文详解Object类和抽象类 2022-09-03
- Spring Cloud Eureka服务注册中心入门流程分析 2023-01-23
- Java8 CompletableFuture runAsync学习总结submit() execute()等 2023-06-30
- Springboot使用SPI注册bean到spring容器的示例代码 2023-06-10
- Java设计模式中的装饰者模式 2023-03-11
- 微信小程序与Java后端接口交互 2023-03-11
- Java外观模式解读,让你的代码优雅又高效 2023-07-15
- Spring3.0配置多个事务管理器的方法 2023-07-31
- springboot通过spel结合aop实现动态传参的案例 2023-03-21