Java 8 memiliki API yang sepenuhnya baru untuk tanggal dan waktu. Salah satu kelas paling berguna dalam API ini adalah LocalDateTime
, untuk memegang nilai tanggal-dengan-waktu-independen-zona waktu.
Mungkin ada jutaan baris kode menggunakan kelas legacy java.util.Date
untuk tujuan ini. Dengan demikian, ketika menghubungkan kode lama dan baru akan ada kebutuhan untuk mengkonversi keduanya. Karena tampaknya tidak ada metode langsung untuk mencapai ini, bagaimana bisa dilakukan?
Jawaban:
Jawaban singkat:
Penjelasan: (berdasarkan pertanyaan ini tentang
LocalDate
)Meskipun namanya,
java.util.Date
mewakili instan di garis waktu, bukan "tanggal". Data aktual yang disimpan dalam objek adalahlong
hitungan milidetik sejak 1970-01-01T00: 00Z (tengah malam pada awal 1970 GMT / UTC).Kelas yang setara dengan
java.util.Date
di JSR-310 adalahInstant
, jadi ada metode yang mudah untuk menyediakan konversi ke sana kemari:Sebuah
java.util.Date
instance tidak memiliki konsep zona waktu. Ini mungkin tampak aneh jika Anda memanggiltoString()
padajava.util.Date
, karenatoString
relatif ke-zona waktu. Namun metode itu benar-benar menggunakan zona waktu default Java on the fly untuk memberikan string. Zona waktu bukan bagian dari keadaan aktualjava.util.Date
.An
Instant
juga tidak mengandung informasi apa pun tentang zona waktu. Jadi, untuk mengkonversi dariInstant
tanggal waktu setempat ke waktu perlu menentukan zona waktu. Ini mungkin zona default -ZoneId.systemDefault()
- atau mungkin zona waktu yang dikontrol aplikasi Anda, seperti zona waktu dari preferensi pengguna.LocalDateTime
memiliki metode pabrik yang nyaman yang menggunakan zona waktu instan dan waktu:Secara terbalik,
LocalDateTime
zona waktu ditentukan dengan memanggilatZone(ZoneId)
metode. TheZonedDateTime
kemudian dapat dikonversi langsung keInstant
:Perhatikan bahwa konversi dari
LocalDateTime
keZonedDateTime
memiliki potensi untuk memperkenalkan perilaku yang tidak terduga. Ini karena tidak setiap tanggal lokal ada karena Waktu Musim Panas. Pada musim gugur / musim gugur, ada tumpang tindih dalam garis waktu lokal di mana waktu tanggal lokal yang sama terjadi dua kali. Di musim semi, ada celah, di mana satu jam menghilang. Lihat JavadocatZone(ZoneId)
untuk lebih banyak definisi tentang apa yang akan dilakukan konversi.Ringkasan, jika Anda pulang pergi
java.util.Date
keLocalDateTime
dan kembali ke,java.util.Date
Anda mungkin berakhir dengan instan berbeda karena Waktu Musim Panas.Info tambahan: Ada perbedaan lain yang akan mempengaruhi tanggal yang sangat lama.
java.util.Date
menggunakan kalender yang berubah pada 15 Oktober 1582, dengan tanggal sebelumnya menggunakan kalender Julian alih-alih kalender Gregorian. Sebaliknya,java.time.*
gunakan sistem kalender ISO (setara dengan Gregorian) untuk sepanjang masa. Dalam kebanyakan kasus penggunaan, sistem kalender ISO adalah yang Anda inginkan, tetapi Anda mungkin melihat efek aneh ketika membandingkan tanggal sebelum tahun 1582.sumber
java.util.Date
tidak mengandung zona waktu, tetapi mencetaknya selamatoString()
. Dokumentasi resmi acara tidak memberitahukan hal ini dengan jelas saat Anda memposting.LocalDateTime.ofInstant(date.toInstant()...
tidak berperilaku seperti yang diharapkan secara naif. Misalnyanew Date(1111-1900,11-1,11,0,0,0);
akan1111-11-17 23:53:28
menggunakan pendekatan ini. Lihatlah implementasijava.sql.Timestamp#toLocalDateTime()
jika Anda membutuhkan hasilnya1111-11-11 00:00:00
pada contoh sebelumnya.java.sql.Date#toInstant
melemparUnsupportedOperationException
. Jadi jangan gunakantoInstant
di RowMapper padajava.sql.ResultSet#getDate
.Inilah yang saya kemukakan (dan seperti semua masalah Date Time, itu mungkin akan ditolak berdasarkan beberapa penyesuaian timezone-leapyear-daylight yang aneh: D)
Bolak-balik:
Date
<<->>LocalDateTime
Diberikan:
Date date = [some date]
(1)
LocalDateTime
<<Instant
<<Date
(2)
Date
<<Instant
<<LocalDateTime
Contoh:
Diberikan:
(1)
LocalDateTime
<<Instant
<<Date
:Buat
Instant
dariDate
:Buat
Date
dariInstant
(tidak perlu, tetapi untuk ilustrasi):Buat
LocalDateTime
dariInstant
(2)
Date
<<Instant
<<LocalDateTime
Buat
Instant
dariLocalDateTime
:Buat
Date
dariInstant
:Outputnya adalah:
sumber
Instant.ofEpochMilli(date.getTime())
melakukannyadate.toInstant()
toInstant()
terlihat bagus, kecuali gagaljava.sql.Date
, arggggh! Jadi akhirnya lebih mudah digunakanInstant.ofEpochMilli(date.getTime())
.Cara yang jauh lebih nyaman jika Anda yakin membutuhkan zona waktu default:
sumber
yang berikut ini tampaknya berfungsi ketika mengonversi dari LocalDateTime API baru ke java.util.date:
konversi sebaliknya dapat (semoga) tercapai dengan cara yang sama ...
semoga membantu ...
sumber
Semuanya ada di sini: http://blog.progs.be/542/date-to-java-time
Jawaban dengan "bolak-balik" tidak tepat: kapan Anda melakukannya
jika zona waktu sistem Anda bukan UTC / GMT, Anda mengubah waktu!
sumber
Cara tercepat untuk
LocalDateTime
->Date
adalah:Date.from(ldt.toInstant(ZoneOffset.UTC))
sumber
Saya tidak yakin apakah ini cara termudah atau terbaik, atau jika ada jebakan, tetapi berhasil:
sumber
LocalDateTime
keDate
. Pada transisi di siang hari, aLocalDateTime
bisa tidak ada, atau terjadi dua kali. Anda perlu memikirkan apa yang Anda inginkan terjadi dalam setiap kasus.GregorianCalendar
milik API canggung lama yangjava.time
bertujuan untuk menggantikan API baruJika Anda menggunakan Android dan menggunakan threetenbp, Anda dapat menggunakannya
DateTimeUtils
.ex:
Anda tidak dapat menggunakan
Date.from
karena hanya didukung pada api 26+sumber