Perbedaan antara Java 8 Date Time API (java.time) dan Joda-Time


264

Saya tahu ada pertanyaan yang berkaitan dengan java.util.Date dan Joda-Time. Tetapi setelah beberapa penggalian, saya tidak dapat menemukan utas tentang perbedaan antara java.time API (baru di Java 8 , didefinisikan oleh JSR 310 ) dan Joda-Time .

Saya telah mendengar bahwa Java.time API Java 8 jauh lebih bersih dan dapat melakukan lebih dari Joda-Time. Tetapi saya tidak dapat menemukan contoh yang membandingkan keduanya.

  • Apa yang bisa dilakukan java.time sehingga Joda-Time tidak bisa?
  • Apa yang bisa java.time lakukan lebih baik daripada Joda-Time?
  • Apakah kinerjanya lebih baik dengan java.time?

8
Bukan, itu berkaitan dengan Java 7, bukan Java 8. Jawaban untuk pertanyaan itu diedit untuk Java 8 dengan sangat sedikit detail. Pertanyaan saya secara khusus adalah menanyakan tentang DateTime API Java 8 yang baru, bukan java.util.Date Java 7. Saya hanya mencari jawaban yang membandingkan Java 8 dengan JodaTime.
Zack

2
mungkin dokumen Oracle ini dapat membantu Anda.
MarioDS

Jika Anda memiliki Java 7, gunakan perpustakaan tambahan, jika Anda memiliki Java 8, gunakan perpustakaan bawaan. Karena kedua perpustakaan pada dasarnya dirancang oleh orang yang sama, saya tidak yakin apa perbedaan utama yang Anda harapkan.
Peter Lawrey

2
@PeterLawrey: Joda-Time dan API tanggal dan waktu Java 8 sebenarnya sangat berbeda.
jarnbjo

5
Anda juga dapat membaca posting blog ini dari Stephen Colbourne - penulis utama kedua proyek.
Matt Johnson-Pint

Jawaban:


416

Fitur umum

a) Kedua perpustakaan menggunakan tipe yang tidak dapat diubah. Joda-Time juga menawarkan jenis bisa berubah tambahan seperti MutableDateTime.

b) Selanjutnya: Kedua perpustakaan terinspirasi oleh studi desain "TimeAndMoney" dari Eric Evans atau ide-ide dari Martin Fowler tentang gaya domain driven sehingga mereka berusaha lebih atau kurang untuk gaya pemrograman yang lancar (meskipun tidak selalu sempurna ;-)).

c) Dengan kedua perpustakaan kami mendapatkan jenis tanggal kalender nyata (disebut LocalDate), jenis waktu dinding nyata (disebut LocalTime) dan komposisi (disebut LocalDateTime). Itu adalah kemenangan yang sangat besar dibandingkan dengan yang lama java.util.Calendardan java.util.Date.

d) Kedua perpustakaan menggunakan pendekatan metode-centric yang berarti mereka mendorong pengguna untuk menggunakan getDayOfYear()bukan get(DAY_OF_YEAR). Ini menyebabkan banyak metode tambahan dibandingkan dengan java.util.Calendar(meskipun yang terakhir tidak aman sama sekali karena penggunaan int yang berlebihan).

Performa

Lihat jawaban lain oleh @ OO7 yang menunjuk pada analisis Mikhail Vorontsov meskipun poin 3 (pengecualian tangkapan) mungkin sudah usang - lihat JDK-bug ini . Performa yang berbeda (yang pada umumnya mendukung JSR-310 ) terutama disebabkan oleh kenyataan bahwa implementasi internal Joda-Time selalu menggunakan waktu-primitif seperti mesin-waktu (dalam milidetik).

Batal

Joda-Time sering menggunakan NULL sebagai default untuk zona waktu sistem, lokal default, timestamp saat ini dll. Sementara JSR-310 hampir selalu menolak nilai NULL.

Presisi

JSR-310 menangani presisi nanodetik sementara Joda-Time terbatas pada presisi milidetik .

Bidang yang didukung:

Tinjauan umum tentang bidang yang didukung di Java-8 (JSR-310) diberikan oleh beberapa kelas dalam paket temporal (misalnya ChronoField dan WeekFields ) sementara Joda-Time agak lemah di area ini - lihat DateTimeFieldType . Kekurangan terbesar Joda-Time di sini adalah tidak adanya bidang terkait minggu yang dilokalkan. Fitur umum dari kedua desain implementasi lapangan adalah bahwa keduanya didasarkan pada nilai-nilai tipe panjang (tidak ada tipe lain, bahkan enum).

Enum

JSR-310 menawarkan enum seperti DayOfWeekatau Monthsementara Joda-Time tidak menawarkan ini karena sebagian besar dikembangkan pada tahun 2002-2004 sebelum Jawa 5 .

API Zona

a) JSR-310 menawarkan lebih banyak fitur zona waktu daripada Joda-Time. Latter tidak dapat menghasilkan akses terprogram untuk sejarah transisi offset zona waktu sementara JSR-310 mampu melakukan ini.

b) Untuk informasi Anda: JSR-310 telah memindahkan repositori zona waktu internal ke lokasi baru dan format lain. Folder perpustakaan lama lib / zi tidak ada lagi.

Adjuster vs Properti

JSR-310 telah memperkenalkan TemporalAdjuster-interface sebagai cara formal untuk mengeksternalisasi perhitungan temporal dan manipulasi, terutama untuk perpustakaan atau kerangka kerja-penulis ini adalah cara yang bagus dan relatif mudah untuk menanamkan ekstensi baru JSR-310 (sejenis setara dengan pembantu statis kelas untuk mantan java.util.Date).

Namun bagi sebagian besar pengguna, fitur ini memiliki nilai yang sangat terbatas karena beban untuk menulis kode masih ada pada pengguna. Solusi TemporalAdjusterbawaan yang didasarkan pada konsep- baru tidak begitu banyak, saat ini hanya ada kelas pembantu TemporalAdjustersdengan serangkaian manipulasi terbatas (dan enum Monthatau tipe temporal lainnya).

Joda-Time menawarkan paket lapangan tetapi praktik telah menunjukkan bukti bahwa implementasi lapangan baru sangat sulit untuk dikodekan. Di sisi lain Joda-Time menawarkan apa yang disebut properti yang membuat beberapa manipulasi lebih mudah dan lebih elegan daripada di JSR-310, misalnya property.withMaximumValue () .

Sistem kalender

JSR-310 menawarkan 4 sistem kalender tambahan. Yang paling menarik adalah Umalqura (digunakan di Arab Saudi). 3 lainnya adalah: Minguo (Taiwan), Jepang (hanya kalender modern sejak 1871!) Dan ThaiBuddhist (hanya benar setelah 1940).

Joda-Time menawarkan kalender Islam berdasarkan pada basis perhitungan - bukan kalender berbasis penampakan seperti Umalqura. Thai-Buddha juga ditawarkan oleh Joda-Time dalam bentuk yang serupa, Minguo dan yang Jepang tidak. Kalau tidak, Joda-Time juga menawarkan kalender coptic dan ethiopic (tetapi tanpa dukungan untuk internasionalisasi).

Lebih menarik bagi orang Eropa: Joda-Time juga menawarkan kalender Gregorian , Julian dan campuran-gregorian-julian. Namun, nilai praktis untuk perhitungan sejarah nyata terbatas karena fitur-fitur penting seperti tahun yang berbeda dimulai pada tanggal tidak didukung sama sekali (kritik yang sama berlaku untuk yang lama java.util.GregorianCalendar).

Kalender lain seperti Ibrani atau Persia atau Hindu benar-benar hilang di kedua perpustakaan.

Zaman dahulu

JSR-310 memiliki kelas JulianFields sementara Joda-Time (versi 2.0) menawarkan beberapa metode penolong di kelas DateTimeUtils .

Jam

JSR-310 tidak memiliki antarmuka (kesalahan desain) tetapi kelas abstrak java.time.Clockyang dapat digunakan untuk injeksi ketergantungan jam apa pun. Joda-Time menawarkan antarmuka MillisProvider dan beberapa metode pembantu di DateTimeUtils sebagai gantinya. Jadi cara ini Joda-Time juga mampu mendukung model yang digerakkan uji dengan jam yang berbeda (mengejek dll.).

Aritmatika durasi

Kedua perpustakaan mendukung perhitungan jarak waktu dalam satu atau lebih unit temporal. Namun, ketika menangani durasi satu unit, gaya JSR-310 jelas lebih bagus (dan berbasis lama daripada menggunakan int):

JSR-310 => long days = ChronoUnit.DAYS.between(date1, date2);

Joda-Time => int days = DAYS.daysBetween(date1, date2).getDays();

Penanganan multi-unit-durasi juga berbeda. Bahkan hasil perhitungan dapat berbeda - lihat masalah Joda-Time yang tertutup ini . Sementara JSR-310 menggunakan pendekatan yang sangat sederhana dan terbatas untuk hanya menggunakan kelas Period(durasi berdasarkan tahun, bulan dan hari) dan Duration(berdasarkan detik dan nanodetik), Joda-Time menggunakan cara yang lebih canggih menggunakan kelas PeriodTypeuntuk mengontrol di mana unit durasi (Joda-Time menyebutnya "Periode") harus dinyatakan. SelagiPeriodType-API entah bagaimana canggung untuk menggunakan cara yang sama tidak ditawarkan oleh JSR-310 sama sekali. Terutama belum dimungkinkan dalam JSR-310 untuk menentukan durasi tanggal dan waktu campuran (berdasarkan hari dan jam misalnya). Jadi berhati-hatilah jika datang ke migrasi dari satu perpustakaan ke yang lain. Perpustakaan dalam diskusi tidak kompatibel - meskipun sebagian nama kelasnya sama.

Interval

JSR-310 tidak mendukung fitur ini sementara Joda-Time memiliki dukungan terbatas. Lihat juga SO-jawaban ini .

Pemformatan dan Parsing

Cara terbaik untuk membandingkan kedua pustaka adalah dengan melihat kelas yang bernama sama DateTimeFormatterBuilder (JSR-310) dan DateTimeFormatterBuilder (Joda-Time). Varian JSR-310 sedikit lebih kuat (juga dapat menangani segala macam TemporalFieldasalkan implementor lapangan telah berhasil mengkodekan beberapa titik ekstensi seperti tekad () ). Perbedaan paling penting adalah - menurut saya:

JSR-310 dapat mem-parsing nama-nama zona waktu yang lebih baik (format simbol pola z) sementara Joda-Time tidak bisa melakukan ini sama sekali dalam versi sebelumnya dan sekarang hanya dengan cara yang sangat terbatas.

Keuntungan lain dari JSR-310 adalah dukungan untuk nama bulan mandiri yang penting dalam bahasa seperti Rusia atau Polandia dll. Joda-Time tidak memiliki akses ke sumber daya tersebut - bahkan pada platform Java-8.

Sintaksis pola dalam JSR-310 juga lebih fleksibel daripada di Joda-Time, memungkinkan untuk bagian opsional (menggunakan tanda kurung siku), lebih berorientasi pada standar CLDR dan menawarkan bantalan (simbol huruf p) dan lebih banyak bidang.

Jika tidak, perlu dicatat bahwa Joda-Time dapat memformat durasi menggunakan PeriodFormatter . JSR-310 tidak dapat melakukan ini.


Semoga ikhtisar ini membantu. Semua informasi yang dikumpulkan terutama ada di sana karena upaya dan investigasi saya bagaimana merancang dan mengimplementasikan perpustakaan tanggal dan waktu yang lebih baik (tidak ada yang sempurna).

Pembaruan dari 2015-06-24:

Sementara itu saya telah menemukan waktu untuk menulis dan menerbitkan ikhtisar tabular untuk berbagai perpustakaan waktu di Jawa. Tabel juga berisi perbandingan antara Joda-Time v2.8.1 dan Java-8 (JSR-310). Itu lebih rinci daripada posting ini.


12
Ini adalah pos yang luar biasa. Terima kasih banyak untuk berbagi semua informasi ini. Jika diberi pilihan antara Joda dan JSR-310 (hanya untuk vanilla use case), mana yang akan Anda pilih? Saya menghadapi pilihan ini sekarang. Saya mempertimbangkan JSR-310, hanya karena ini lebih baru dan saya mencoba mendukung "bergerak maju" sedapat mungkin.
kevinarpe

7
@ kevinarpe Jika saya hanya memiliki pilihan antara JSR-310 dan Joda-Time, saya mungkin lebih suka JSR-310 karena Joda-Time hampir menghentikan pengembangan lebih lanjut (fitur besar baru tidak dapat diharapkan - hanya perbaikan bug dan pembaruan kecil). Dan desain JSR-310 hanya lebih modern (dan dengan kualitas internal yang lebih baik). Ngomong-ngomong dan tidak mengejutkan, keputusan saya yang sebenarnya adalah lebih suka perpustakaan saya Time4J - lihat juga tautan ke ikhtisar tabular yang diberikan di bagian bawah posting saya. Itu selalu baik untuk memiliki alternatif, dan itu sangat tergantung pada fitur apa yang Anda butuhkan.
Meno Hochschild

Bukankah Durasi versi Java8 dari Interval?
Christian Hujer

1
@ChristianHujer Tidak, java.time.Durationtidak dapat ditanyakan untuk awal atau akhir, berbeda dengan interval yang berlabuh pada timeline. Tipe JSR-310 ini hanya sepasang detik berlalu dan nanodetik sejak awal yang tidak diketahui.
Meno Hochschild

42

Tanggal / Waktu Java 8:

  1. Kelas Java 8 dibangun sekitar waktu manusia. Itu membuat mereka cepat untuk aritmatika / konversi dataman manusia.
  2. Getter komponen tanggal / waktu seperti getDayOfMonthmemiliki kompleksitas O (1) dalam implementasi Java 8.
  3. Parsing of OffsetDateTime/ OffsetTime/ ZonedDateTimesangat lambat di Java 8 ea b121 karena pengecualian dilemparkan dan ditangkap secara internal di JDK.
  4. Satu set paket: java.time.*, java.time.chrono.*, java.time.format.*, java.time.temporal.*,java.time.zone.*
  5. Instants (cap waktu) Tanggal dan Waktu Tanggal Parsial dan Waktu Parser dan zona waktu Formatter Kronologi yang berbeda (kalender).
  6. Kelas yang ada memiliki masalah seperti Date tidak memiliki dukungan untuk I18N atau L10N. Mereka bisa berubah!
  7. Lebih sederhana & lebih kuat.
  8. Jam bisa disuntikkan.
  9. Jam dapat dibuat dengan berbagai properti - Jam statis, jam Mocked, jam presisi rendah (seluruh detik, menit penuh, dll).
  10. Jam dapat dibuat dengan zona waktu tertentu. Clock.system(Zone.of("America/Los_Angeles")).
  11. Membuat tanggal dan waktu penanganan kode dapat diuji.
  12. Membuat tes independen terhadap zona waktu.

Joda-Time:

  1. Joda-Time menggunakan waktu mesin di dalam. Implementasi manual berdasarkan nilai int / long akan jauh lebih cepat.
  2. Getter Joda-Time memerlukan perhitungan waktu komputer-ke-manusia pada setiap panggilan getter, yang membuat Joda-Time menjadi hambatan dalam skenario seperti itu.
  3. Ini terdiri dari kelas yang tidak berubah yang menangani Instants, Tanggal & Waktu, Partial, dan Durasi. Fleksibel. Dirancang dengan baik.
  4. Merupakan tanggal sebagai contoh. Tetapi tanggal & waktu dapat berhubungan dengan lebih dari satu instan. Jam tumpang tindih saat penghematan siang hari berakhir. Dan juga tidak memiliki instan yang sesuai dengan itu sama sekali. Celah jam saat siang hari dimulai. Harus melakukan perhitungan yang rumit untuk operasi sederhana.
  5. Menerima nulls sebagai nilai yang valid pada sebagian besar metodenya. Menghasilkan bug yang halus.

Untuk perbandingan lebih detail, lihat: -

Java 8 Date / Time library performance (juga Joda-Time 2.3 dan juCalendar) . & API Tanggal & Waktu Baru di Java 8


Ketika Anda mengatakan "Lakukan tes independen terhadap zona waktu." Apa yang sebenarnya Anda maksud dengan itu?
Zack

@Zack: Mungkin jika Anda menguji kode, yang berperilaku berbeda tergantung pada zona waktu, Anda mungkin diminta untuk memaksa tes untuk berjalan dengan zona waktu default yang berbeda dari apa yang disediakan oleh sistem operasi.
jarnbjo

Hah - Saya pikir Anda mengatakan bahwa joda secara internal berlari pada mesin waktu daripada waktu mesin ... Dan saya tidak akan terkejut
Kyranstar

4
@ OO7 Apa maksudmu 'waktu manusia'? Lagi pula, waktu dihitung oleh mesin.
IgorGanapolsky

1

Joda-Time sekarang dalam mode pemeliharaan

Bukan jawaban langsung untuk pertanyaan tetapi proyek Joda-Time tidak lagi dalam pengembangan aktif. Tim menyarankan pengguna untuk bermigrasi ke java.time API yang lebih baru . Lihat tutorial oleh Oracle .

Dari halaman proyek GitHub resmi :

Joda-time tidak lagi dalam pengembangan aktif kecuali untuk menjaga data zona waktu tetap terbaru. Dari Java SE 8 dan seterusnya, pengguna diminta untuk bermigrasi ke java.time (JSR-310) - bagian inti dari JDK yang menggantikan proyek ini. Untuk pengguna Android, java.time ditambahkan dalam API 26+. Proyek yang perlu mendukung level API yang lebih rendah dapat menggunakan pustaka ThreeTenABP.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.