Apa perbedaan antara ZonedDateTime dan OffsetDateTime?

155

Saya sudah membaca dokumentasinya, tetapi saya masih belum bisa mendapatkannya ketika saya harus menggunakan satu atau yang lain:

Menurut dokumentasi OffsetDateTimeharus digunakan saat menulis tanggal ke database, tapi saya tidak mengerti mengapa.

Zhenya
sumber
4
Pada dasarnya a ZonedDateTimejuga berisi informasi tentang zona waktu, termasuk DST switching dll dari apa yang saya baca.
fge

Jawaban:

187

T: Apa perbedaan antara java 8 ZonedDateTime dan OffsetDateTime?

Javascript mengatakan ini:

" OffsetDateTime, ZonedDateTimedan Instantsemua menyimpan instan pada garis waktu hingga ketepatan nanodetik. Instantadalah yang paling sederhana, hanya mewakili instan. OffsetDateTimeMenambahkan ke instan offset dari UTC / Greenwich, yang memungkinkan tanggal-waktu lokal diperoleh. ZonedDateTimemenambahkan waktu penuh aturan-zona. "

Sumber: https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html

Dengan demikian perbedaan antara OffsetDateTimedan ZonedDateTimeadalah bahwa yang terakhir mencakup aturan yang mencakup penyesuaian waktu siang hari dan berbagai anomali lainnya.

Secara sederhana:

Zona Waktu = ( Offset-Dari-UTC + Aturan-Untuk-Anomali)


T: Menurut dokumentasi OffsetDateTime harus digunakan saat menulis tanggal ke database, tapi saya tidak mengerti mengapa.

Tanggal dengan offset waktu lokal selalu mewakili waktu yang sama dalam waktu, dan karenanya memiliki pemesanan yang stabil. Sebaliknya, makna tanggal dengan informasi zona waktu penuh tidak stabil dalam menghadapi penyesuaian aturan untuk zona waktu masing-masing. (Dan ini benar-benar terjadi; mis. Untuk nilai waktu-tanggal di masa mendatang.) Jadi jika Anda menyimpan dan mengambil ZonedDateTimeimplementasi, ada masalah:

  • Ia dapat menyimpan offset yang dihitung ... dan objek yang diambil mungkin memiliki offset yang tidak konsisten dengan aturan saat ini untuk id zona-.

  • Ini dapat membuang offset yang dihitung ... dan objek yang diambil kemudian mewakili titik berbeda dalam timeline absolut / universal daripada yang disimpan.

Jika Anda menggunakan serialisasi objek Java, implementasi Java 9 mengambil pendekatan pertama. Ini bisa dibilang cara "lebih benar" untuk menangani ini, tetapi ini tampaknya tidak didokumentasikan. (Driver JDBC dan binding ORM mungkin membuat keputusan yang sama, dan semoga bisa memperbaikinya.)

Tetapi jika Anda menulis aplikasi yang secara manual menyimpan nilai tanggal / waktu, atau yang bergantung pada java.sql.DateTime, maka berurusan dengan komplikasi dari id zona adalah ... mungkin sesuatu yang harus dihindari. Karena itu sarannya.

Perhatikan bahwa tanggal yang artinya / pemesanannya tidak stabil dari waktu ke waktu mungkin bermasalah untuk suatu aplikasi. Dan karena perubahan pada aturan zona adalah kasus tepi, masalahnya akan muncul pada waktu yang tidak terduga.


Alasan (mungkin) kedua untuk saran ini adalah bahwa konstruksi a ZonedDateTimeadalah ambigu pada poin-poin tertentu. Misalnya dalam periode waktu ketika Anda "mengembalikan jam", menggabungkan waktu lokal dan id zona dapat memberi Anda dua offset yang berbeda. The ZonedDateTimekonsisten akan memilih satu atas yang lain ... tapi ini tidak selalu pilihan yang tepat.

Sekarang, ini bisa menjadi masalah untuk aplikasi apa pun yang membangun ZonedDateTimenilai seperti itu. Tetapi dari perspektif seseorang membangun aplikasi perusahaan adalah masalah yang lebih besar ketika nilai-nilai (mungkin salah) ZonedDateTimepersisten dan digunakan kemudian.

Stephen C
sumber