Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
不支持操作异常-为什么可以';您不能在java.sql.Date上调用toInstant()?_Java_Java 8_Java Time - Fatal编程技术网

不支持操作异常-为什么可以';您不能在java.sql.Date上调用toInstant()?

不支持操作异常-为什么可以';您不能在java.sql.Date上调用toInstant()?,java,java-8,java-time,Java,Java 8,Java Time,java.util.Date类有一个名为toInstant()的方法,该方法将Date实例转换为java.time.Instant java.sql.Date类扩展了java.util.Date类,但是当我试图在java.sql.Date上调用toInstant()时,我收到一个不支持操作异常 为什么toInstant()在java.sql.Date上是不受支持的操作 什么是将java.sql.Date转换为java.time.Instant的“正确”方法 由于sql.Date没有时间组件,因此

java.util.Date
类有一个名为
toInstant()
的方法,该方法将
Date
实例转换为
java.time.Instant

java.sql.Date
类扩展了
java.util.Date
类,但是当我试图在
java.sql.Date
上调用
toInstant()
时,我收到一个
不支持操作异常

为什么
toInstant()
java.sql.Date
上是不受支持的操作

什么是将
java.sql.Date
转换为
java.time.Instant
的“正确”方法

由于
sql.Date
没有时间组件,因此无法将其转换为
time.Instant

此方法始终引发不支持的OperationException,并且应该 无法使用,因为SQL日期值没有时间组件

仅支持日期组件(日期、月、年)。它不支持时间组件(小时、分钟、秒、毫秒)。需要日期和时间组件,因此toInstant on java.sql.Date实例引发UnsupportedOperationException异常

toInstant Java文档

这种方法总是抛出一个错误 由于SQL日期,因此不应使用UnsupportedOperationException和 值没有时间组件

java.util.Date或java.sql.Timestamp都有日期/时间组件,所以toInstant()可以工作

您可以这样做:

// Time is 00:00:00.000

new java.util.Date(sqlDate.getTime()).toInstant() 
更新:

Instant.ofEpochMilli(sqlDate.getTime());

// OR
new java.util.Date(sqlDate.getTime()).toInstant();
将返回相同的结果,因为toInstant()在内部调用Instant.ofEpochMilli(getTime())

public Instant toInstant() {
    return Instant.ofEpochMilli(getTime());
}

到目前为止给出的答案都集中在
java.sql.Date
没有时间信息的细节上。这是正确的,但不是该类型无法直接转换为
即时
的真正或充分原因。不幸的是,他们也犯了同样的错误,让用户认为问题仅仅是因为缺少时间信息

从概念上讲,类型
java.sql.Date
表示本地类型。它模拟了一个日历日期,在全球任何地区都可能不同。但在全球范围内,
即时
是一样的因此用户需要时区或时区偏移来进行转换。

不幸的是,类型
java.sql.Date
继承自
java.util.Date
,这是一种全局类型(类似即时)。然而,这种继承实际上表示实现继承,而不是类型继承。考虑这些旧JDBC类的设计将被打破的另一个原因。因此,确实可以使用hack通过其方法
getTime()
java.sql.Date
封装在
java.util.Date
的实例中,从而最终允许直接转换为即时。但是:此转换隐式使用系统的默认时区

那么,如何以迂腐的方式正确地转换?让我们再考虑一下,这里指向正确的方向:

java.sql.Date sqlDate = ...;
LocalDate calendarDate = sqlDate.toLocalDate();
ZonedDateTime zdt = calendarDate.atStartOfDay(ZoneId.of("Europe/Paris"));
Instant instant = zdt.toInstant();

java.sql.Date
java.time
之间的正确映射是
LocalDate

LocalDate date = sqlDate.toLocalDate();
如果确实需要,则可以派生一个
即时
,尽管额外的信息(时间)是任意的。例如:

Instant i = date.atStartOfDay(ZoneOffset.UTC).toInstant();

如果约会中没有时间,请将其转换为毫秒:

Instant.ofEpochMilli(date.getTime())
   .atZone(ZoneId.systemDefault())
   .toLocalDate();

哪个更“正确”<代码>Instant.ofEpochMilli(sqlDate.getTime())
新建java.util.Date(sqlDate.getTime()).toInstant()如果不提供时区,则无法将java.sql.Date转换为瞬间。在java.sql.Date上调用getTime()毫无意义。正如在其他评论中指出的,java.sql.Date只是一个LocalDate,并不代表时间上的瞬间。我确实在Javautil日期调用了instant,在这种情况下没有问题。现在,问题是为什么它是这样设计的。可以想象它的默认时间信息设置为0。在邮件列表中找不到任何内容。@Tunaki该逻辑使我认为这是因为父类
util.Date
有一个public
toInstant
方法,子类不应使用该方法。因此,他们宁愿选择覆盖它并使其不可用,而不是使其成为最终的(保留继承逻辑)。@Tunaki可能是因为,正如您所指出的,任何转换为瞬间的操作都需要任意设置一些数据(时间、时区)。希望我能接受两个答案。。。这完美地回答了我问题的第二部分,但主要问题是为什么不能在
java.sql.Date
上调用
toInstant()
,因此我不得不接受的。这个答案需要更多的投票。