Saya tahu itu:
- Instan lebih merupakan representasi stempel waktu "teknis" (nanodetik) untuk komputasi.
- LocalDateTime lebih merupakan representasi tanggal / jam termasuk zona waktu untuk manusia.
Masih pada akhirnya IMO keduanya dapat dianggap sebagai tipe untuk sebagian besar kasus penggunaan aplikasi. Sebagai contoh: Saat ini saya menjalankan pekerjaan batch di mana saya perlu menghitung putaran berikutnya berdasarkan tanggal dan saya berjuang untuk menemukan pro / kontra antara kedua jenis ini (terlepas dari keunggulan presisi nanosecond dari Instant dan bagian zona waktu) dari LocalDateTime).
Bisakah Anda menyebutkan beberapa contoh aplikasi, di mana hanya Instant atau LocalDateTime yang harus digunakan?
Sunting: Hati-hati salah membaca dokumentasi untuk LocalDateTime mengenai ketepatan dan zona waktu
LocalDateTime
tidak tidak memiliki zona waktu!Jawaban:
tl; dr
Instant
danLocalDateTime
dua binatang yang sama sekali berbeda: Yang satu mewakili momen, yang lain tidak.Instant
mewakili momen, titik tertentu dalam timeline.LocalDateTime
mewakili tanggal dan waktu. Tetapi tidak memiliki zona waktu atau offset-dari-UTC, kelas ini tidak dapat mewakili momen . Ini mewakili momen potensial sepanjang kisaran sekitar 26 hingga 27 jam, rentang semua zona waktu di seluruh dunia.Anggapan yang Salah
Pernyataan Anda salah: A tidak
LocalDateTime
memiliki zona waktu . Tidak memiliki zona waktu adalah inti dari kelas itu.Mengutip dokumen kelas itu:
Jadi
Local…
berarti "tidak dikategorikan, tidak diimbangi".Instant
An
Instant
adalah momen pada timeline di UTC , hitungan nanodetik sejak zaman pertama UTC 1970 (pada dasarnya, lihat dokumen kelas untuk detail seluk-beluk). Karena sebagian besar logika bisnis, penyimpanan data, dan pertukaran data Anda harus dalam UTC, ini adalah kelas praktis yang sering digunakan.OffsetDateTime
Kelas
OffsetDateTime
kelas mewakili momen sebagai tanggal dan waktu dengan konteks sejumlah jam-menit-detik di depan, atau di belakang, UTC. Jumlah offset, jumlah jam-menit-detik, diwakili olehZoneOffset
kelas.Jika jumlah jam-menit-detik adalah nol, suatu
OffsetDateTime
mewakili momen di UTC sama denganInstant
.ZoneOffset
The
ZoneOffset
kelas merupakan offset-dari-UTC , sejumlah jam-menit-detik menjelang UTC atau di belakang UTC.A
ZoneOffset
hanyalah sejumlah jam-menit-detik, tidak lebih. Zona jauh lebih, memiliki nama dan riwayat perubahan untuk diimbangi. Jadi menggunakan zona selalu lebih baik daripada menggunakan offset belaka.ZoneId
Sebuah zona waktu diwakili oleh
ZoneId
kelas.Misalnya, hari baru tiba di Paris daripada di Montréal , misalnya. Jadi kita perlu menggerakkan jarum jam untuk lebih merefleksikan siang (ketika Matahari langsung di atas kepala) untuk wilayah tertentu. Semakin jauh ke timur / barat dari garis UTC di Eropa barat / Afrika semakin besar offset.
Zona waktu adalah seperangkat aturan untuk menangani penyesuaian dan anomali seperti yang dilakukan oleh komunitas atau wilayah setempat. Anomali yang paling umum adalah kegilaan yang terlalu populer yang dikenal sebagai Daylight Saving Time (DST) .
Zona waktu memiliki sejarah aturan masa lalu, aturan saat ini, dan aturan dikonfirmasi untuk waktu dekat.
Aturan-aturan ini berubah lebih sering daripada yang Anda harapkan. Pastikan untuk menjaga aturan perpustakaan tanggal-waktu Anda, biasanya salinan database 'tz' , terbaru. Tetap mutakhir lebih mudah dari sebelumnya di Java 8 dengan Oracle merilis Timezone Updater Tool .
Tentukan nama zona waktu yang tepat dalam format
Continent/Region
, sepertiAmerica/Montreal
,Africa/Casablanca
, atauPacific/Auckland
. Jangan pernah menggunakan singkatan 2-4 huruf sepertiEST
atauIST
karena mereka bukan zona waktu yang sebenarnya, tidak terstandarisasi, dan bahkan tidak unik (!).ZonedDateTime
Pikirkan secara
ZonedDateTime
konseptual sebagaiInstant
dengan tugasZoneId
.Untuk menangkap momen saat ini seperti yang terlihat pada waktu jam dinding yang digunakan oleh orang-orang di wilayah tertentu (zona waktu):
Hampir semua backend Anda, database, logika bisnis, kegigihan data, pertukaran data semua harus dalam UTC. Tetapi untuk presentasi kepada pengguna, Anda perlu menyesuaikan ke dalam zona waktu yang diharapkan oleh pengguna. Ini adalah tujuan dari
ZonedDateTime
kelas dan kelas formatter yang digunakan untuk menghasilkan representasi String dari nilai-nilai tanggal-waktu tersebut.Anda dapat menghasilkan teks dalam format lokal menggunakan
DateTimeFormatter
.LocalDate
,LocalTime
,LocalDateTime
"Lokal" kelas waktu tanggal,
LocalDateTime
,LocalDate
,LocalTime
, adalah jenis yang berbeda dari makhluk. Tidak terikat dengan satu lokalitas atau zona waktu. Mereka tidak terikat dengan timeline. Mereka tidak memiliki arti yang nyata sampai Anda menerapkannya ke suatu daerah untuk menemukan titik pada timeline.Kata "Lokal" dalam nama-nama kelas ini mungkin kontra-intuitif bagi yang belum tahu. Kata itu berarti setiap lokalitas, atau setiap lokalitas, tetapi bukan lokalitas tertentu.
Jadi untuk aplikasi bisnis, tipe "Lokal" tidak sering digunakan karena hanya mewakili gagasan umum tentang kemungkinan tanggal atau waktu, bukan momen spesifik di timeline. Aplikasi bisnis cenderung peduli kapan tepatnya faktur tiba, produk dikirim untuk transportasi, karyawan dipekerjakan, atau taksi meninggalkan garasi. Jadi pengembang aplikasi bisnis menggunakan
Instant
danZonedDateTime
kelas yang paling umum.Jadi kapan kita akan menggunakan
LocalDateTime
? Dalam tiga situasi: di mana kami ingin menerapkan tanggal dan waktu tertentu di beberapa lokasi, di mana kami memesan janji temu, atau di mana kami memiliki zona waktu yang dimaksudkan namun belum ditentukan. Perhatikan bahwa tidak satu pun dari ketiga kasus ini adalah satu titik spesifik tertentu pada timeline, tidak ada yang merupakan momen.Suatu saat, beberapa saat
Terkadang kami ingin mewakili waktu tertentu pada hari tertentu, tetapi ingin menerapkannya di beberapa tempat di zona waktu.
Misalnya, "Natal dimulai pada tengah malam pada tanggal 25 Desember 2015" adalah a
LocalDateTime
. Midnight menyerang pada saat-saat berbeda di Paris daripada di Montréal, dan berbeda lagi di Seattle dan Auckland .Contoh lain, "Perusahaan Acme memiliki kebijakan bahwa jam makan siang dimulai pukul 12:30 malam di setiap pabriknya di seluruh dunia" adalah a
LocalTime
. Untuk memiliki makna yang sebenarnya, Anda perlu menerapkannya pada timeline untuk mengetahui momen 12:30 di pabrik Stuttgart atau 12:30 di pabrik Rabat atau 12:30 di pabrik Sydney .Janji pemesanan
Situasi lain yang digunakan
LocalDateTime
adalah untuk pemesanan acara mendatang (mis: janji dokter gigi). Penunjukan ini mungkin cukup jauh di masa depan sehingga Anda berisiko politisi mendefinisikan ulang zona waktu. Politisi sering memberi sedikit peringatan, atau bahkan tidak ada peringatan sama sekali. Jika Anda bermaksud "15:00 23 Januari mendatang" terlepas dari bagaimana politisi dapat bermain dengan jam, maka Anda tidak dapat merekam sesaat - yang akan melihat 15:00 berubah menjadi 14:00 atau 16:00 jika wilayah itu mengadopsi atau menjatuhkan Daylight Saving Time, sebagai contoh.Untuk janji temu, simpan a
LocalDateTime
dan aZoneId
, disimpan secara terpisah. Kemudian, ketika membuat jadwal, sambil menentukan waktu dengan meneleponLocalDateTime::atZone( ZoneId )
untuk menghasilkanZonedDateTime
objek.Jika perlu, Anda dapat menyesuaikan ke UTC. Ekstrak
Instant
dariZonedDateTime
.Zona tidak dikenal
Beberapa orang mungkin menggunakan
LocalDateTime
dalam situasi di mana zona waktu atau offset tidak diketahui.Saya menganggap kasus ini tidak pantas dan tidak bijaksana. Jika zona atau offset dimaksudkan tetapi tidak ditentukan, Anda memiliki data yang buruk. Itu seperti menyimpan harga suatu produk tanpa mengetahui mata uang yang dituju. Bukan ide yang bagus.
Semua tipe waktu tanggal
Untuk kelengkapan, berikut adalah tabel dari semua tipe tanggal yang mungkin, baik yang modern maupun yang lama di Jawa, serta yang ditentukan oleh standar SQL. Ini mungkin membantu menempatkan
Instant
&LocalDateTime
kelas dalam konteks yang lebih besar.Perhatikan pilihan aneh yang dibuat oleh tim Java dalam merancang JDBC 4.2. Mereka memilih untuk mendukung semua waktu java.time ... kecuali untuk dua kelas yang paling sering digunakan:
Instant
&ZonedDateTime
.Tapi tidak perlu khawatir. Kita dapat dengan mudah mengkonversi bolak-balik.
Konversi
Instant
.Konversi
ZonedDateTime
.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 .sumber
Local
penamaan. Intuisi saya akanLocal
sarana dalam kaitannya dengan keberadaan saya DAN ketika saya (?!), Yang membuat saya percaya bahwa itu akan menjadi apa adanyaZonedDateTime
.DateTime
nama kelas yang digunakan oleh pendahulunya Joda-Time (memproduksiZonedDateTime
), untuk menekankan perbedaan dari kelas "Lokal". Pikirkan nama "Lokal" sebagai singkatan untuk "perlu diterapkan ke beberapa daerah tertentu".Local
mungkin juga merupakan cara untuk membedakan dari paket java.util, meskipun entah bagaimana saya merasa mungkin ada pilihan kata yang lebih baik.Satu perbedaan utama adalah
Local
bagian dariLocalDateTime
. Jika Anda tinggal di Jerman dan membuatLocalDateTime
contoh dan orang lain tinggal di AS dan membuat contoh lain pada saat yang sama (asalkan jam diatur dengan benar) - nilai benda-benda itu sebenarnya akan berbeda. Ini tidak berlaku untukInstant
, yang dihitung secara independen dari zona waktu.LocalDateTime
menyimpan tanggal dan waktu tanpa zona waktu, tetapi nilai awalnya bergantung pada zona waktu.Instant
bukan.Selain itu,
LocalDateTime
menyediakan metode untuk memanipulasi komponen tanggal seperti hari, jam, bulan. AnInstant
tidak.Kedua kelas memiliki presisi yang sama.
LocalDateTime
tidak menyimpan zona waktu. Baca javadocs secara menyeluruh, karena Anda dapat membuat kesalahan besar dengan asumsi yang tidak valid: Instant dan LocalDateTime .sumber
LocalDateTime stores date and time without timezone, but it's initial value is timezone dependent
? apa nilai awal dan bagaimana tergantung zona waktu? Terima kasih.Anda salah tentang
LocalDateTime
: itu tidak menyimpan informasi zona waktu dan memiliki presisi nanodetik. Mengutip Javadoc (penekanan milik saya):Perbedaan antara keduanya adalah yang
Instant
mewakili offset dari Epoch (01-01-1970) dan, dengan demikian, mewakili instan tertentu pada garis waktu. DuaInstant
objek yang dibuat pada saat yang sama di dua tempat berbeda di Bumi akan memiliki nilai yang persis sama.sumber
Instant
sesuai dengan waktu di meridian utama (Greenwich).Sedangkan
LocalDateTime
relatif terhadap pengaturan zona waktu OS, dansumber