2016-04-05 15 views
24

java.util.DateクラスにはtoInstant()というメソッドがあり、Dateインスタンスをjava.time.Instantに変換します。UnsupportedOperationException - java.sql.DateでtoInstant()を呼び出せないのはなぜですか?

java.sql.Dateクラスはjava.util.Dateクラスを拡張し、私はjava.sql.DatetoInstant()を呼び出そうとするとき、私はUnsupportedOperationExceptionを受けます。

java.sql.DatetoInstant()がサポートされない理由は何ですか?

java.sql.Datejava.time.Instantに変換する「正しい」方法は何ですか?

答えて

12

sql.Dateは時間コンポーネントを持たないので、この方法は、常にUnsupportedOperationExceptionをスローし、 SQL日ので、使用しないでくださいtime.Instant

に変換する可能性がないJavaDoc

をチェック値には時間成分がありません。

+1

ここで、質問はこのように設計されています。時間情報が0に設定されているとデフォルト設定されていると思います。メーリングリストに何も見つかりません。 – Tunaki

+2

@Tunaki親クラス 'util.Date'には、子クラスで使われるべきではないpublic' toInstant'メソッドがあるので、それは論理だと思います。したがって、継承ロジックを維持するために「最終」にするのではなく、継承ロジックをオーバーライドして使用できなくするオプションが好まれていました。 –

+0

@Tunakiおそらく、あなたが指摘しているように、インスタントに変換するには、何らかのデータを任意に設定する必要があるからです(時間、時間帯)。 – assylias

13

java.sql.Dateは、日付、月、および年のみをサポートします。時間情報はサポートしていません。

java.sql.Date.toInstant()がUnsupportedOperationExceptionをスローする理由です。 Java 8 Instantには、日付と時刻の両方の情報が含まれています。

java.util.Dateには日付と時刻の両方の情報が含まれているため、java.util.Date.toInstant()Works!

あなたはこのように行うことができます。

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()); 
} 
+0

どちらが「正しい」ですか? –

+0

java.sql.DateをInstantなしでInstantに変換することはできません。タイムゾーンを提供する。 java.sql.DateでgetTime()を呼び出すことは無意味です。他のコメントで指摘されているように、java.sql.DateはLocalDateだけであり、瞬間を表すものではありません。 –

+0

java sqlの日付でtoInstantを呼び出さなかった。私はJavaユーティリティの日付についてtoInstantを呼び出しましたが、大文字小文字は問題ありません。 – Loc

9

今まで、これまでに与えられた答えはjava.sql.Date時間がない情報を持っていないことを詳細に集中します。これは正解ですが、このタイプがInstantに直接変換できない実質的または十分な理由ではありません。不幸にも、documentation of Java-8は、ユーザーが時刻情報が欠落しているだけであると考えるようにするのと同じ間違いを犯しています。

概念的には、タイプjava.sql.Dateはローカルタイプを表します。これは、地球のどの地域でも異なるカレンダーの日付をモデル化します。しかし、Instantは私たちの地球上では同じです。 したがって、ユーザーは変換を行うためにタイムゾーンまたはタイムゾーンオフセットが必要です。

悲惨なことに、タイプjava.sql.Dateは、グローバルタイプ(インスタントのような)であるjava.util.Dateを継承します。ただし、この継承は実際に継承を表すのではなく、継承継承を示します。これらの古いJDBCクラスの設計が壊れていると考えるもう一つの理由。したがって、java.sql.DategetTime()のインスタンスでjava.util.Dateのインスタンスの中にラップするためにハックを使用することは本当に可能であり、最終的に瞬時に直接変換することができます。しかし、この変換では、暗黙的にシステムのデフォルトのタイムゾーンが使用されます。

どのように正しく賢明な方法で変換するには?のは、ここに右方向に指しdocumentation of Java-8もう一度考えてみましょう:

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

java.sql.Datejava.time間の正しいマッピングがLocalDate次のとおりです。

LocalDate date = sqlDate.toLocalDate(); 

あなたが本当には、あなたがしてInstantを導き出すことができなければならない場合余分な情報(時間)は任意です。例:

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

私は2つの答えを受け入れることができます...これは私の質問の2番目の部分に完全に答えますが、主な質問は 'java.sql.Date'で' toInstant() 'を呼び出せない理由でした。 [@ YassinHajaj](http://stackoverflow.com/users/5050667/yassin-hajaj)の[回答](http://stackoverflow.com/a/36435570/2561365)を受け入れます。この答えはより多くのupvotesを必要とします。 –

関連する問題