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
UnsupportedOperationException - Why can't you call toInstant() on a java.sql.Date?
提问by Andrew Mairose
The java.util.Date
class has a method called toInstant()
that converts the Date
instance to a java.time.Instant
.
该java.util.Date
班有一个名为方法toInstant()
是转换Date
实例到java.time.Instant
。
The java.sql.Date
class extends the java.util.Date
class, 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.Date
to a java.time.Instant
?
将 a 转换java.sql.Date
为 a的“正确”方法是java.time.Instant
什么?
采纳答案by Yassin Hajaj
Check the JavaDoc
检查JavaDoc
Since sql.Date
does 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.Date
has 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.Date
represents a local type. It models a calendar date which can be different in any region of our globe. But an Instant
is 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.Date
inherits from java.util.Date
which 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.Date
via its method getTime()
inside an instance of java.util.Date
which 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.Date
via 其方法包装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.Date
and java.time
is LocalDate
:
java.sql.Date
和之间的正确映射java.time
是LocalDate
:
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();