在没有* toInstant()的情况下将java.util.Date截断为LocalDate *,因为java.sql.Date给出了UnsupportedOperationException
作者:互联网
如果我在一个恰好是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,因此最好始终明确指出您正在使用的时区.
标签:java,date,datetime,java-time,date-conversion 来源: https://codeday.me/bug/20190611/1216765.html