JavaRush /Java Blog /Random-ID /Pustaka yang intuitif dan tangguh untuk bekerja dengan wa...
theGrass
Level 24
Саратов

Pustaka yang intuitif dan tangguh untuk bekerja dengan waktu dan tanggal akhirnya tersedia di Java (Bagian 1).

Dipublikasikan di grup Random-ID
Java     akhirnya memiliki cara yang intuitif dan andal untuk menangani tanggal dan waktu. Prinsip tanggal dan waktu merupakan hal mendasar dalam banyak penerapan. Berbagai hal seperti tanggal lahir, tanggal sewa, waktu acara, dan jam buka toko semuanya berdasarkan tanggal dan waktu, namun Java SE tidak menyediakan cara yang nyaman untuk bekerja dengannya. Dimulai dengan Java SE 8 , ada satu set paket java.time - yang menyediakan API terstruktur dengan baik untuk bekerja dengan tanggal dan waktu.
Latar belakang
    Ketika Java pertama kali keluar, pada versi 1.0 , satu-satunya kelas yang bekerja dengan tanggal dan waktu adalah java.util.Date . Hal pertama yang diperhatikan pengembang adalah bahwa itu tidak mewakili “tanggal”. Faktanya, ini mewakili momen dalam waktu, akurat hingga milidetik, diukur sejak tanggal 1 Januari 1970. Namun, berdasarkan fakta bahwa metode toString() Date menampilkan tanggal dan waktu dalam zona waktu yang ditentukan dalam pengaturan java mesin , beberapa pengembang secara keliru menyimpulkan bahwa Date dapat bekerja dengan zona waktu. Memperbaiki kelas ini ternyata sangat sulit (atau sangat malas) sehingga di versi 1.1 kami harus menambahkan kelas baru - java.util.Calendar . Sayangnya, kelas Calendar ternyata tidak jauh lebih baik dari Date . Berikut daftar kecil permasalahan yang ada dalam implementasinya:
  • Dapat diubah. Kelas seperti tanggal dan waktu tidak boleh diubah.
  • offset. Tahun dalam Tanggal dimulai dari tahun 1900, bulan di kedua kelas dimulai dari nol.
  • Nama. Tanggal sebenarnya bukan "tanggal", dan Kalender bukanlah kalender.
  • Pemformatan. Pemformatan hanya berfungsi dengan Tanggal, bukan Kalender, dan tidak aman untuk thread.
    Pada tahun 2001, proyek Joda-Time dibuat . Tujuannya sederhana - untuk membuat perpustakaan berkualitas tinggi untuk bekerja dengan tanggal dan waktu di Java . Butuh beberapa waktu, namun versi 1.0 akhirnya dirilis dan dengan cepat menjadi sangat populer dan banyak digunakan. Seiring waktu, pengembang semakin menuntut agar perpustakaan dengan kemudahan serupa disediakan sebagai bagian dari JDK . Dengan partisipasi Michael Nascimento Santos dari Brazil, proyek JSR-310 diluncurkan , yang merupakan proses resmi untuk membuat dan mengintegrasikan API baru untuk bekerja dengan tanggal dan waktu di JDK .
Tinjauan
Java.time API baru berisi 5 paket:
  • java.time - paket dasar yang berisi objek untuk menyimpan nilai
  • java.time.chrono - menyediakan akses ke kalender yang berbeda
  • java.time.format - pemformatan dan pengenalan tanggal dan waktu
  • java.time.temporal - perpustakaan tingkat rendah dan fungsionalitas tingkat lanjut
  • java.time.zone - kelas untuk bekerja dengan zona waktu
    Sebagian besar pengembang akan menggunakan paket dasar dan pemformatan, dan mungkin java.time.temporal . Jadi, meski sudah ditambahkan 68 tipe baru, pengembang hanya akan menggunakan sekitar sepertiganya.
tanggal
    Kelas LocalDate adalah salah satu yang paling penting dalam API baru . Ini berisi nilai abadi yang mewakili tanggal. Anda tidak dapat mengatur waktu atau zona waktu. Nama "lokal" mungkin asing bagi Anda dari Joda-Time , dan aslinya berasal dari standar ISO-8601 . Artinya justru tidak adanya zona waktu. Pada dasarnya, LocalDate adalah deskripsi suatu tanggal, seperti "5 April 2014". Waktu sebenarnya pada tanggal ini akan berbeda tergantung pada zona waktu Anda. Misalnya, di Australia tanggal ini akan terjadi 10 jam lebih awal dibandingkan di London, dan 18 jam lebih awal dibandingkan di San Francisco. Kelas LocalDate memiliki semua metode yang umum dibutuhkan: LocalDate date = LocalDate.of(2014, Month.JUNE, 10); int year = date.getYear(); // 2014 Month month = date.getMonth(); // Июнь int dom = date.getDayOfMonth(); // 10 DayOfWeek dow = date.getDayOfWeek(); // Вторник int len = date.lengthOfMonth(); // 30 (дней в Июне) boolean leap = date.isLeapYear(); // false (не високосный год)     Dalam contoh kita, kita melihat tanggal dibuat menggunakan metode pabrik (semua konstruktor bersifat pribadi). Selanjutnya kita meminta beberapa data pada objek tersebut. Harap dicatat bahwa enumerasi Month dan DayOfWeek dirancang untuk membuat kode lebih mudah dibaca dan diandalkan. Dalam contoh berikut kita akan melihat cara mengubah tanggal. Karena kelasnya tidak dapat diubah, hasilnya akan berupa objek baru, namun objek asli akan tetap seperti semula. LocalDate date = LocalDate.of(2014, Month.JUNE, 10); date = date.withYear(2015); // 2015-06-10 date = date.plusMonths(2); // 2015-08-10 date = date.minusDays(1); // 2015-08-09     Ini adalah perubahan yang relatif sederhana, namun sering kali Anda perlu melakukan modifikasi tanggal yang lebih rumit. Ada mekanisme khusus untuk ini di java.time API - TemporalAdjuster . Tujuannya adalah untuk menyediakan alat bawaan yang memungkinkan Anda memanipulasi tanggal, misalnya mendapatkan objek yang sesuai dengan hari terakhir dalam sebulan. Beberapa di antaranya disertakan dalam API , tetapi Anda dapat menambahkannya sendiri. Menggunakan pengubah sangat mudah, tetapi memerlukan impor statis: import static java.time.DayOfWeek.* import static java.time.temporal.TemporalAdjusters.* LocalDate date = LocalDate.of(2014, Month.JUNE, 10); date = date.with(lastDayOfMonth()); date = date.with(nextOrSame(WEDNESDAY));     Menggunakan pengubah sangat menyederhanakan kode Anda. Tidak seorang pun ingin melihat banyak manipulasi tanggal manual. Jika semacam manipulasi tanggal terjadi beberapa kali dalam proyek Anda, tulis pengubah Anda sendiri dan tim Anda dapat menggunakannya sebagai komponen yang sudah ditulis dan diuji.
Waktu dan tanggal sebagai nilai
    Ada baiknya meluangkan sedikit waktu untuk memahami apa yang membuat LocalDate bernilai. Nilai adalah tipe data sederhana yang sepenuhnya dapat dipertukarkan; jika nilainya sama, identitas objek menjadi tidak berarti. Contoh klasik dari kelas nilai adalah String . Kami membandingkan string menggunakan equal() , dan kami tidak peduli apakah objeknya identik jika dibandingkan dengan == operator . Sebagian besar kelas untuk bekerja dengan tanggal dan waktu juga merupakan nilai. Jadi, membandingkannya menggunakan operator == adalah ide yang buruk, seperti yang dinyatakan dalam dokumentasi. Bagi mereka yang tertarik untuk mempelajari lebih lanjut, lihat definisi terbaru saya tentang VALJOs , yang menguraikan serangkaian aturan ketat yang harus diikuti oleh objek nilai di Java , termasuk kekekalan, metode pabrik, dan definisi yang tepat dari equal() , hashCode , toString() , dan bandingkanTo .() .
Kalender alternatif
    Kelas LocalDate , seperti semua kelas utama di java.time , terikat pada satu kalender - seperti yang dijelaskan dalam standar ISO-8601 . Standar 8601 menjelaskan kalender standar dunia, yang juga dikenal sebagai kalender Gregorian. Tahun standar mencakup 365 hari, tahun kabisat - 366. Setiap tahun keempat adalah tahun kabisat kecuali habis dibagi 100 atau habis dibagi 400. Tahun sebelum tahun pertama era baru dianggap nol untuk memudahkan perhitungan. Konsekuensi pertama dari sistem default ini adalah hasilnya tidak selalu sesuai dengan yang dihitung menggunakan GregorianCalendar . Kelas GregorianCalendar memiliki saklar bawaan ke sistem Julian untuk semua tanggal sebelum 15 Oktober 1582. Dalam sistem Julian, setiap tahun keempat merupakan tahun kabisat, tanpa kecuali. Pertanyaannya adalah, karena transisi dari satu sistem ke sistem lainnya adalah fakta sejarah, mengapa java.time tidak memodelkannya? Ya, karena negara-negara yang berbeda beralih ke sistem Gregorian pada waktu yang berbeda, dan hanya dengan mempertimbangkan tanggal transisi Vatikan, kita akan mendapatkan data yang salah untuk sebagian besar negara lain. Misalnya, Kerajaan Inggris, termasuk koloni-koloni di Amerika Utara, beralih ke kalender Gregorian pada tanggal 14 September 1752, hampir 200 tahun kemudian. Rusia baru mengubah kalendernya pada tanggal 14 Februari 1918, dan transisi Swedia pada umumnya tidak begitu jelas. Akibatnya, arti sebenarnya dari tanggal sebelum tahun 1918 sangat bervariasi tergantung pada keadaan. Penulis kode LocalDate membuat keputusan yang sepenuhnya rasional untuk tidak memodelkan transisi dari kalender Julian ke kalender Gregorian sama sekali untuk menghindari perbedaan. Konsekuensi kedua dari penggunaan ISO-8601 sebagai kalender default di semua kelas inti adalah diperlukan serangkaian kelas tambahan untuk menangani kalender yang tersisa. Antarmuka Kronologi adalah dasar untuk bekerja dengan kalender alternatif, memungkinkan Anda menemukan kalender yang diinginkan berdasarkan nama lokal. Java 8 hadir dengan 4 kalender tambahan - Buddha Thailand, Mingguo (Taiwan), Jepang dan Islam. Kalender lain mungkin dilengkapi dengan program. Setiap kalender memiliki kelas tanggal khusus seperti ThaiBuddhistDate , MinguoDate , JapaneseDate dan HijrahDate . Masuk akal untuk menggunakannya dalam aplikasi yang sangat terlokalisasi, misalnya untuk pemerintah Jepang. Antarmuka tambahan, ChronoLocalDate , digunakan sebagai abstraksi inti dari empat kelas di atas bersama dengan LocalDate, yang memungkinkan Anda menulis kode terlepas dari jenis kalender yang digunakan. Meskipun abstraksi ini ada, namun penggunaannya tidak disarankan. Memahami mengapa abstraksi ini tidak disarankan penting untuk memahami cara kerja seluruh java.time API . Intinya adalah sebagian besar kode yang ditulis tanpa mengacu pada kalender tertentu ternyata tidak berfungsi. Misalnya, Anda tidak dapat memastikan bahwa ada 12 bulan dalam satu tahun, namun beberapa pengembang menambahkan 12 bulan dan berpikir bahwa mereka telah menambahkan satu tahun penuh. Anda tidak dapat memastikan bahwa semua bulan berisi jumlah hari yang kira-kira sama - dalam kalender Koptik ada 12 bulan yang terdiri dari 30 hari, dan 1 bulan yang terdiri dari lima atau enam hari. Selain itu, Anda tidak dapat memastikan bahwa jumlah tahun berikutnya akan lebih banyak 1 dari tahun sekarang, karena dalam penanggalan Jepang, tahun dihitung sejak proklamasi kaisar berikutnya (dalam hal ini, genap 2 hari di bulan yang sama. dapat berasal dari tahun yang berbeda). Satu-satunya cara untuk menulis kode berkualitas tinggi dan berfungsi yang berfungsi dengan beberapa kalender sekaligus adalah bahwa inti kode Anda, yang melakukan semua operasi pada tanggal dan waktu, harus ditulis menggunakan kalender standar, dan hanya saat memasukkan/mengeluarkan tanggal haruskah itu dikonversi ke sistem kalender lain. Artinya, disarankan untuk menggunakan LocalDate untuk penyimpanan dan semua manipulasi tanggal di aplikasi Anda. Dan hanya ketika melokalisasi tanggal input dan output Anda harus menggunakan ChronoLocalDate , yang biasanya diperoleh dari kelas kalender yang disimpan di profil pengguna. Benar, sebagian besar aplikasi tidak memerlukan lokalisasi yang serius. Jika Anda memerlukan penjelasan lebih rinci tentang semua yang dijelaskan dalam bab ini, selamat datang di dokumentasi kelas ChronoLocalDate .      Kelanjutan artikel      Artikel asli
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION