UnsupportedOperationException - 为什么不能在 java.sql.Date 上调用 toInstant()?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36435492/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 17:53:14  来源:igfitidea点击:

UnsupportedOperationException - Why can't you call toInstant() on a java.sql.Date?

javajava-8java-time

提问by Andrew Mairose

The java.util.Dateclass has a method called toInstant()that converts the Dateinstance to a java.time.Instant.

java.util.Date班有一个名为方法toInstant()是转换Date实例到java.time.Instant

The java.sql.Dateclass extends the java.util.Dateclass, but when I attempt to call toInstant()on a java.sql.Date, I receive an UnsupportedOperationException.

java.sql.Date类扩展了java.util.Date类,但是当我尝试调用toInstant()java.sql.Date,我收到一个UnsupportedOperationException

Why is toInstant()an unsupported operation on java.sql.Date?

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

And what is the "correct" way to convert a java.sql.Dateto a java.time.Instant?

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

采纳答案by Yassin Hajaj

Check the JavaDoc

检查JavaDoc

Since sql.Datedoes not have a time component, there is no possibility to convert it to time.Instant

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

This method always throws an UnsupportedOperationException and should not be used because SQL Date values do not have a time component.

此方法始终抛出 UnsupportedOperationException 并且不应使用,因为 SQL 日期值没有时间组件。

回答by Loc

java.sql.Datesupports only Date components (date, month, year). It does NOT support time components (hour, minute, second, millisecond). toInstantrequires both Date and Time components so toInstant on java.sql.Date instance throws UnsupportedOperationException exception.

java.sql.Date仅支持日期组件(日期、月份、年份)。它不支持时间组件(小时、分钟、秒、毫秒)。toInstant需要 Date 和 Time 组件,因此 java.sql.Date 实例上的 toInstant 会抛出 UnsupportedOperationException 异常。

toInstant Java doc

toInstant Java 文档

This method always throws an UnsupportedOperationException and should not be used because SQL Date values do not have a time component.

此方法始终抛出 UnsupportedOperationException 并且不应使用,因为 SQL 日期值没有时间组件。

java.util.Date OR java.sql.Timestamp has both Date/Time components so toInstant() works!

java.util.Date OR java.sql.Timestamp 有两个日期/时间组件,所以 toInstant() 可以工作!

You can do like this:

你可以这样做:

// Time is 00:00:00.000

new java.util.Date(sqlDate.getTime()).toInstant() 

Updated:

更新:

Instant.ofEpochMilli(sqlDate.getTime());

// OR
new java.util.Date(sqlDate.getTime()).toInstant();

Will return the same result because toInstant() call Instant.ofEpochMilli(getTime()) internally.

将返回相同的结果,因为 toInstant() 在内部调用 Instant.ofEpochMilli(getTime())。

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

回答by Meno Hochschild

The answers given so far until now concentrate on the detail that java.sql.Datehas no time information. That is correct but not the real or sufficient reason why this type cannot offer a direct conversion to Instant. Unfortunatly the documentation of Java-8does make the same mistake to let users think the problem is just because of missing time information.

到目前为止给出的答案都集中在java.sql.Date没有时间信息的细节上。这是正确的,但不是这种类型不能直接转换为Instant. 不幸的是,Java-8文档确实犯了同样的错误,让用户认为问题只是因为缺少时间信息。

Conceptually, the type java.sql.Daterepresents a local type. It models a calendar date which can be different in any region of our globe. But an Instantis the same on our globe around. So users need a timezone or a timezone offset to do the conversion.

从概念上讲,该类型java.sql.Date表示本地类型。它模拟了一个日历日期,该日期在我们全球的任何地区都可能不同。但是Instant在我们的地球上也是一样的。所以用户需要一个时区或时区偏移量来进行转换。

Tragically, the type java.sql.Dateinherits from java.util.Datewhich is a global type (instant-like). However, this inheritance really denotes implementation inheritance, and not type inheritance. One more reason to consider the design of these old JDBC-classes to be broken. Therefore it is indeed possible to use the hack to wrap the java.sql.Datevia its method getTime()inside an instance of java.util.Datewhich finally allows direct conversion to an instant. But: This conversion implicitly uses the default timezone of the system.

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

So how to correctly convert in a pedantic way? Let's consider the documentation of Java-8again which here points into the right direction:

那么如何以迂腐的方式正确转换呢?让我们再次考虑Java-8文档,它指出了正确的方向:

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

回答by assylias

The correct mapping between java.sql.Dateand java.timeis LocalDate:

java.sql.Date和之间的正确映射java.timeLocalDate

LocalDate date = sqlDate.toLocalDate();

If you really must, you can then derive an Instant, although the extra information (time) will be arbitrary. For example:

如果您确实必须,则可以推导出Instant,尽管额外信息(时间)将是任意的。例如:

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