私のindex.htmlには<input type="datetime-local">
フィールドがあり、ユーザーが選択した値でMySqlデータベースを更新する必要があります。私のデータベースフィールドは現在タイムスタンプです。このdatetime-local値でデータベースを更新できるようにするupdateステートメントを作成するにはどうすればよいですか?私は多くのオプションを試しましたが、現在の試みを以下に示します。ただし、これは機能しません。私はこれをすべてJavaで行っています。
String updateStatement = "UPDATE cars SET reservation = ? WHERE uniqueID = ?";
pStmt = con.prepareStatement(updateStatement);
pStmt.setTimestamp(1, reservation);
pStmt.setTimestamp(2, someUniqueId);
特定のコードの質問に答えるには(ただし、これは予定/予約を処理するための間違った方法です):
myPreparedStatement
.setObject(
1 ,
ZonedDateTime
.of
(
LocalDate.of( 2021 , Month.JANUARY , 23 ) ,
LocalTime.of( 15 , 30 ) ,
ZoneId.of( "Africa/Tunis" )
)
.toInstant()
.atOffset( ZoneOffset.UTC )
)
;
TIMESTAMP
MySQLのタイプは、UTCから0時間-分-秒のオフセットから見た、タイムライン上の特定のポイントである瞬間を追跡するためのものであり、マイクロ秒に解決されます。これはTIMESTAMP WITH TIME ZONE
、標準SQLにマップされます。
Javaでの適切な一致はjava.time.Instant
です。このクラスもUTCで見られる瞬間を表しますが、ナノ秒のより細かい解像度で表示されます。
残念ながら、JDBC 4.2仕様では、瞬間を追跡する3つのタイプのうちの1つのみをサポートする必要がありますOffsetDateTime
。Instant
とZonedDateTime
は両方ともJDBC4.2ではオプションです。したがって、特定のJDBCドライバーはをサポートする場合とサポートしない場合がありInstant
ます。JDBCチームによるこの設計上の決定は、私を困惑させます。間の変換Instant
とOffsetDateTime
全く簡単で、JDBC仕様で要求されている必要があります。
特定のタイムゾーン内の日付と時刻をユーザーが選択できるようにしていると思います。しかし、あなたがあなたの入力を詳述することを怠ったので、私はよくわかりません。
LocalDate localDate = LocalDate.of( 2021 , Month.JANUARY , 23 ) ;
LocalTime localTime = LocalTime.of( 15 , 30 ) ;
ZoneId zoneId = ZoneId.of( "America/Edmonton" ) ;
ZonedDateTime zdt = ZonedDateTime.of( localDate, localTime , zoneId ) ;
データベースに保存するには、タイムゾーンからUTC(ゼロのオフセット)に調整しましょう。以下からの変換ZonedDateTime
にInstant
し、その後にOffsetDateTime
ゼロ時間-分-秒定数によって表されるのオフセットを持ちますZoneOffset.UTC
。
OffsetDateTime odt = zdt.toInstant().atOffset( ZoneOffset.UTC ) ; // Use `OffsetDateTime` rather than `Instant` for maximum compatibility across JDBC 4.2 drivers.
を呼び出さないでくださいPreparedStatement#setTimestamp
。そのメソッドは、ひどいjava.sql.Timestamp
クラスにとって、今ではレガシーです。java.time
パッケージの外部で日時クラスを使用しないでください。これらのレガシークラスは、数年前にJSR310で定義された最新のjava.timeクラスに取って代わられました。
を呼び出しPreparedStatement#setObject
ます。JDBCチームはset…
、さまざまなjava.timeクラスの特定のメソッドをまだ定義していません。繰り返しますが、私を困惑させる設計上の決定。ただし、/を使用してjava.timeオブジェクトを交換できます。setObject
getObject
myPreparedStatement.setObject( … , odt ) ;
検索。
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
ちなみに、ビジネス上の問題は将来のレストランの予約だとおっしゃいました。この仕事のために、あなたは間違ったアプローチを取っています。
そのような将来の予定をされていない瞬間として追跡、あるいないタイムライン上の特定の点。政治家がそのタイムゾーンで使用されるオフセットを変更した場合、顧客は、政治家が時計を前後に動かしても、午後7時のレストランの予約が午後7時にとどまると予想します。同様に、政治家がオフセットを変更した場合でも、4か月後の午後3時の歯科予約は午後3時にとどまる必要があります。そして、世界中の政治家は、タイムゾーンのオフセットを変更することを楽しんでいます。これは驚くほど頻繁に発生し、事前の警告も少なくなります。
予約/予定は、タイムゾーンなしの日付と時刻として追跡し、データベースの2番目の列にタイムゾーンを個別に保存する必要があります。これらのタイプはTIMESTAMP WITHOUT TIME ZONE
、標準SQLとDATETIME
MySQLにあります。また、タイムゾーン識別子にはテキストタイプを使用します。Javaでのマッチングタイプは次のようになりますLocalDateTime
とZoneId
。予定表の実行時に、を組み合わせて瞬間を決定しZonedDateTime
ます。
私と他の著者は、すでにStackOverflowでこれを何度も取り上げています。したがって、詳細については検索してください。
java.timeフレームワークは、Java8以降に組み込まれています。これらのクラスは面倒古い取って代わるレガシーのような日付時刻クラスをjava.util.Date
、Calendar
、& SimpleDateFormat
。
詳細については、Oracleチュートリアルを参照してください。そして、StackOverflowで多くの例と説明を検索してください。仕様はJSR310です。
ジョダタイムプロジェクトは、今でメンテナンスモードへの移行をアドバイスjava.timeのクラス。
java.timeオブジェクトをデータベースと直接交換できます。JDBC4.2以降に準拠したJDBCドライバーを使用してください。文字列もクラスも必要ありません。Hibernate5およびJPA2.2はjava.timeをサポートします。java.sql.*
java.timeクラスはどこで入手できますか?
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加