tl; dr
Bagaimana cara mengubah java.util.Date ke java.sql.Date?
Jangan. Kedua kelas sudah ketinggalan zaman.
- Gunakan kelas java.time bukan warisan
java.util.Date
& java.sql.Date
dengan JDBC 4.2 atau yang lebih baru.
- Konversikan ke / dari java.time jika inter-operasi dengan kode belum diperbarui ke java.time.
Contoh kueri dengan PreparedStatement
.
myPreparedStatement.setObject(
… , // Specify the ordinal number of which argument in SQL statement.
myJavaUtilDate.toInstant() // Convert from legacy class `java.util.Date` (a moment in UTC) to a modern `java.time.Instant` (a moment in UTC).
.atZone( ZoneId.of( "Africa/Tunis" ) ) // Adjust from UTC to a particular time zone, to determine a date. Instantiating a `ZonedDateTime`.
.toLocalDate() // Extract a date-only `java.time.LocalDate` object from the date-time `ZonedDateTime` object.
)
Penggantian:
Instant
dari pada java.util.Date
Keduanya mewakili momen di UTC. tapi sekarang dengan nanodetik, bukan milidetik.
LocalDate
dari pada java.sql.Date
Keduanya menunjukkan nilai hanya tanggal tanpa waktu dalam sehari dan tanpa zona waktu.
Detail
Jika Anda mencoba untuk bekerja dengan nilai hanya tanggal (tanpa waktu, tanpa zona waktu), gunakan LocalDate
kelas daripada java.util.Date
.
waktu java
Di Java 8 dan yang lebih baru, kelas tanggal-waktu lama yang bermasalah yang dibundel dengan versi awal Java telah digantikan oleh paket java.time yang baru . Lihat Tutorial Oracle . Sebagian besar fungsi telah di-porting ke Java 6 & 7 di ThreeTen-Backport dan selanjutnya diadaptasi ke Android di ThreeTenABP .
Sebuah tipe data SQL DATE
dimaksudkan untuk menjadi tanggal-satunya, dengan tidak ada waktu-of-hari dan tidak ada zona waktu. Java tidak pernah memiliki kelas seperti itu † sampai java.time.LocalDate
di Jawa 8. Mari kita membuat nilai seperti itu dengan mendapatkan tanggal hari ini sesuai dengan zona waktu tertentu (zona waktu penting dalam menentukan tanggal sebagai hari baru fajar lebih awal di Paris daripada di Montréal, karena contoh).
LocalDate todayLocalDate = LocalDate.now( ZoneId.of( "America/Montreal" ) ); // Use proper "continent/region" time zone names; never use 3-4 letter codes like "EST" or "IST".
Pada titik ini, kita mungkin sudah selesai. Jika driver JDBC Anda sesuai dengan spesifikasi JDBC 4.2 , Anda harus bisa mengirimkan LocalDate
via setObject
pada PreparedStatement
untuk menyimpan ke bidang SQL DATE.
myPreparedStatement.setObject( 1 , localDate );
Demikian juga, gunakan ResultSet::getObject
untuk mengambil dari kolom SQL DATE ke LocalDate
objek Java . Menentukan kelas dalam argumen kedua membuat kode Anda aman .
LocalDate localDate = ResultSet.getObject( 1 , LocalDate.class );
Dengan kata lain, seluruh Pertanyaan ini tidak relevan di bawah JDBC 4.2 atau yang lebih baru.
Jika driver JDBC Anda tidak berkinerja dengan cara ini, Anda harus kembali ke konversi ke tipe java.sql.
Konversikan ke java.sql.Date
Untuk mengonversi, gunakan metode baru yang ditambahkan ke kelas tanggal-waktu yang lama. Kita dapat menelepon java.sql.Date.valueOf(…)
untuk mengonversi a LocalDate
.
java.sql.Date sqlDate = java.sql.Date.valueOf( todayLocalDate );
Dan pergi ke arah lain.
LocalDate localDate = sqlDate.toLocalDate();
Konversi dari java.util.Date
Meskipun Anda harus menghindari menggunakan kelas waktu-tanggal yang lama, Anda mungkin dipaksa ketika bekerja dengan kode yang ada. Jika demikian, Anda dapat mengonversi ke / dari java.time.
Telusuri Instant
kelas, yang mewakili momen dalam timeline di UTC. Sebuah Instant
mirip ide untuk sebuah java.util.Date
. Tetapi perhatikan bahwa Instant
memiliki resolusi hingga nanodetik sementara java.util.Date
hanya memiliki resolusi milidetik .
Untuk mengonversi, gunakan metode baru yang ditambahkan ke kelas lama. Sebagai contoh, java.util.Date.from( Instant )
dan java.util.Date::toInstant
.
Instant instant = myUtilDate.toInstant();
Untuk menentukan tanggal, kita perlu konteks zona waktu. Untuk setiap momen tertentu, tanggalnya bervariasi di seluruh dunia berdasarkan zona waktu. Terapkan ZoneId
untuk mendapatkan ZonedDateTime
.
ZoneId zoneId = ZoneId.of ( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant ( instant , zoneId );
LocalDate localDate = zdt.toLocalDate();
Berpura-pura kelas † The java.sql.Date menjadi tanggal-hanya tanpa waktu-of-hari tetapi sebenarnya tidak waktu-of-hari, disesuaikan dengan waktu tengah malam. Membingungkan? Ya, kelas tanggal-waktu lama berantakan.
Tentang java.time
The java.time kerangka dibangun ke Jawa 8 dan kemudian. Kelas-kelas ini menggantikan tua merepotkan warisan kelas tanggal-waktu seperti java.util.Date
, Calendar
, & SimpleDateFormat
.
Proyek Joda-Time , sekarang dalam mode pemeliharaan , menyarankan migrasi ke kelas java.time .
Untuk mempelajari lebih lanjut, lihat Tutorial Oracle . Dan cari Stack Overflow untuk banyak contoh dan penjelasan. Spesifikasi adalah JSR 310 .
Anda dapat bertukar objek java.time secara langsung dengan database Anda. Gunakan driver JDBC yang sesuai dengan JDBC 4.2 atau yang lebih baru. Tidak perlu untuk string, tidak perlu untuk java.sql.*
kelas.
Di mana mendapatkan kelas java.time?
Proyek ThreeTen-Extra memperpanjang java.time dengan kelas tambahan. Proyek ini adalah ajang pembuktian untuk kemungkinan penambahan masa depan ke java.time. Anda mungkin menemukan beberapa kelas berguna di sini seperti Interval
, YearWeek
, YearQuarter
, dan lebih .