JavaRush /Blog Java /Random-MS /Perpustakaan yang intuitif dan mantap untuk bekerja denga...
theGrass
Tahap
Саратов

Perpustakaan yang intuitif dan mantap untuk bekerja dengan masa dan tarikh akhirnya tersedia di Java (Bahagian 1).

Diterbitkan dalam kumpulan
Java     akhirnya mempunyai cara yang intuitif dan boleh dipercayai untuk bekerja dengan tarikh dan masa. Prinsip tarikh dan masa adalah asas dalam banyak aplikasi. Pelbagai perkara seperti tarikh lahir, tarikh sewa, masa acara dan waktu buka kedai semuanya berdasarkan tarikh dan masa, tetapi Java SE tidak menyediakan cara yang mudah untuk bekerja dengan mereka. Bermula dengan Java SE 8 , terdapat satu set pakej java.time - yang menyediakan API yang tersusun dengan baik untuk bekerja dengan tarikh dan masa.
Latar belakang
    Apabila Java mula-mula keluar, dalam versi 1.0 , satu-satunya kelas untuk bekerja dengan tarikh dan masa ialah java.util.Date . Perkara pertama yang diperhatikan oleh pembangun ialah ia tidak mewakili "tarikh". Malah, ia mewakili detik dalam masa, tepat kepada milisaat, diukur dari tarikh 1 Januari 1970. Walau bagaimanapun, berdasarkan fakta bahawa kaedah Date 's toString() memaparkan tarikh dan masa dalam zon waktu yang dinyatakan dalam tetapan java mesin , sesetengah pembangun tersilap membuat kesimpulan bahawa Date boleh berfungsi dengan zon waktu. Membetulkan kelas ini ternyata sangat sukar (atau sangat malas) sehingga dalam versi 1.1 kami terpaksa menambah kelas baharu - java.util.Calendar . Malangnya, kelas Kalendar ternyata tidak lebih baik daripada Date . Berikut adalah senarai kecil masalah sedia ada dalam pelaksanaannya:
  • Boleh tukar. Kelas seperti tarikh dan masa hendaklah tidak berubah.
  • Offset. Tahun dalam Tarikh bermula dari 1900, bulan dalam kedua-dua kelas bermula dari sifar.
  • Nama. Tarikh sebenarnya bukan "tarikh", dan Kalendar bukan kalendar.
  • Memformat. Pemformatan hanya berfungsi dengan Tarikh, bukan Kalendar, dan tidak selamat untuk urutan.
    Pada tahun 2001, projek Joda-Time telah dicipta . Matlamatnya adalah mudah - untuk mencipta perpustakaan berkualiti tinggi untuk bekerja dengan tarikh dan masa di Java . Ia mengambil sedikit masa, tetapi versi 1.0 akhirnya dikeluarkan dan dengan cepat menjadi sangat popular dan digunakan secara meluas. Dari masa ke masa, pembangun semakin menuntut agar perpustakaan kemudahan yang sama disediakan sebagai sebahagian daripada JDK . Dengan penyertaan Michael Nascimento Santos dari Brazil, projek JSR-310 telah dilancarkan , yang merupakan proses rasmi untuk mencipta dan menyepadukan API baharu untuk bekerja dengan tarikh dan masa dalam JDK .
Semakan
API java.time baharu mengandungi 5 pakej:
  • java.time - pakej asas yang mengandungi objek untuk menyimpan nilai
  • java.time.chrono - menyediakan akses kepada kalendar yang berbeza
  • java.time.format - pemformatan dan pengecaman tarikh dan masa
  • java.time.temporal - perpustakaan peringkat rendah dan fungsi lanjutan
  • java.time.zone - kelas untuk bekerja dengan zon waktu
    Kebanyakan pembangun akan menggunakan pakej asas dan pemformatan, dan mungkin java.time.temporal . Jadi, walaupun 68 jenis baharu telah ditambah, pembangun hanya akan menggunakan kira-kira satu pertiga daripadanya.
kurma
    Kelas LocalDate ialah salah satu yang paling penting dalam API baharu . Ia mengandungi nilai tidak berubah yang mewakili tarikh. Anda tidak boleh menetapkan masa atau zon waktu. Nama "tempatan" mungkin biasa kepada anda daripada Joda-Time , dan asalnya berasal daripada standard ISO-8601 . Ia bermakna tepat ketiadaan zon waktu. Pada asasnya, LocalDate ialah perihalan tarikh, seperti "5 April 2014". Masa sebenar tarikh ini akan berbeza bergantung pada zon waktu anda. Sebagai contoh, di Australia tarikh ini akan menjadi 10 jam lebih awal daripada di London, dan 18 jam lebih awal daripada di San Francisco. Kelas LocalDate mempunyai semua kaedah yang biasa diperlukan: 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 kami, kami melihat tarikh dibuat menggunakan kaedah kilang (semua pembina adalah peribadi). Seterusnya kami meminta objek untuk beberapa data. Sila ambil perhatian bahawa penghitungan Bulan dan DayOfWeek direka untuk menjadikan kod lebih mudah dibaca dan boleh dipercayai. Dalam contoh berikut kita akan melihat cara mengubah suai tarikh. Oleh kerana kelas tidak boleh diubah, hasilnya akan menjadi objek baharu, tetapi yang asal akan kekal seperti sedia ada. 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 agak mudah, tetapi selalunya anda perlu membuat pengubahsuaian tarikh yang lebih kompleks. Terdapat mekanisme khas untuk ini dalam API java.time - TemporalAdjuster . Tujuannya adalah untuk menyediakan alat terbina dalam yang membolehkan anda memanipulasi tarikh, contohnya mendapatkan objek yang sepadan dengan hari terakhir bulan itu. Sebahagian daripadanya disertakan dalam API , tetapi anda boleh menambah sendiri. Menggunakan pengubah suai adalah sangat mudah, tetapi ia memerlukan import statik: 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 suai sangat memudahkan kod anda. Tiada siapa yang mahu melihat banyak manipulasi tarikh manual. Jika beberapa jenis manipulasi tarikh berlaku beberapa kali dalam projek anda, tulis pengubah suai anda sendiri dan pasukan anda boleh menggunakannya sebagai komponen yang telah ditulis dan diuji.
Masa dan tarikh sebagai nilai
    Anda perlu meluangkan sedikit masa untuk memahami perkara yang menjadikan LocalDate sebagai nilai. Nilai ialah jenis data mudah yang boleh ditukar ganti sepenuhnya; apabila ia sama, identiti objek menjadi tidak bermakna. Contoh klasik kelas nilai ialah String . Kami membandingkan rentetan menggunakan equals() , dan kami tidak peduli sama ada objek adalah sama jika dibandingkan dengan operator == . Kebanyakan kelas untuk bekerja dengan tarikh dan masa juga merupakan nilai. Jadi, membandingkannya menggunakan operator == adalah idea yang tidak baik, seperti yang dinyatakan dalam dokumentasi. Bagi mereka yang berminat untuk mengetahui lebih lanjut, lihat definisi terbaru saya tentang VALJOs , yang menggariskan satu set peraturan yang ketat yang menghargai objek dalam Java mesti ikut , termasuk kebolehubah, kaedah kilang dan takrifan yang betul bagi equals() , hashCode , toString() , dan bandingkanKepada .() .
Kalendar alternatif
    Kelas LocalDate , seperti semua kelas utama dalam java.time , terikat pada satu kalendar - seperti yang diterangkan dalam piawaian ISO-8601 . Piawaian 8601 menerangkan kalendar piawai sedunia, juga dikenali sebagai kalendar Gregorian. Tahun piawai termasuk 365 hari, tahun lompat - 366. Setiap tahun keempat ialah tahun lompat melainkan boleh dibahagi dengan 100 atau boleh dibahagi dengan 400. Tahun sebelum tahun pertama era baharu dianggap sifar untuk memudahkan pengiraan. Akibat pertama daripada ini menjadi sistem lalai ialah keputusan tidak selalu sepadan dengan yang dikira menggunakan GregorianCalendar . Kelas GregorianCalendar mempunyai suis terbina dalam kepada sistem Julian untuk semua tarikh sebelum 15 Oktober 1582. Dalam sistem Julian, setiap tahun keempat adalah tahun lompat, tanpa pengecualian. Persoalannya, memandangkan peralihan dari satu sistem ke sistem yang lain adalah fakta sejarah, mengapa java.time tidak memodelkannya? Ya, kerana negara yang berbeza bertukar kepada sistem Gregorian pada masa yang berbeza, dan hanya mengambil kira tarikh peralihan Vatican, kami akan mendapat data yang salah untuk kebanyakan negara lain. Sebagai contoh, Empayar British, termasuk tanah jajahan di Amerika Utara, bertukar kepada kalendar Gregorian pada 14 September 1752, hampir 200 tahun kemudian. Rusia tidak menukar kalendarnya sehingga 14 Februari 1918, dan peralihan Sweden pada umumnya adalah perkara yang keruh. Akibatnya, makna sebenar tarikh sebelum 1918 sangat berbeza bergantung pada keadaan. Pengarang kod LocalDate membuat keputusan yang rasional sepenuhnya untuk tidak memodelkan peralihan daripada kalendar Julian kepada kalendar Gregorian sama sekali, untuk mengelakkan percanggahan. Akibat kedua menggunakan ISO-8601 sebagai kalendar lalai dalam semua kelas teras ialah set kelas tambahan diperlukan untuk mengendalikan kalendar yang tinggal. Antara muka Kronologi ialah asas untuk bekerja dengan kalendar alternatif, membolehkan anda mencari kalendar yang dikehendaki mengikut nama tempat. Java 8 dilengkapi dengan 4 kalendar tambahan - Thai Buddha, Mingguo (Taiwan), Jepun dan Islam. Kalendar lain mungkin disertakan dengan program. Setiap kalendar mempunyai kelas tarikh istimewa seperti ThaiBuddhistDate , MinguoDate , JapaneseDate dan HijrahDate . Adalah masuk akal untuk menggunakannya dalam aplikasi yang sangat setempat, seperti untuk kerajaan Jepun. Antara muka tambahan, ChronoLocalDate , digunakan sebagai abstraksi teras bagi empat kelas di atas bersama-sama dengan LocalDate, yang membolehkan anda menulis kod bebas daripada jenis kalendar yang digunakan. Walaupun abstraksi ini wujud, penggunaannya tidak disyorkan. Memahami sebab abstraksi ini tidak disyorkan adalah penting untuk memahami cara keseluruhan API java.time berfungsi . Intinya ialah kebanyakan kod yang ditulis tanpa merujuk kepada kalendar tertentu ternyata tidak berfungsi. Sebagai contoh, anda tidak pasti bahawa terdapat 12 bulan dalam setahun, tetapi sesetengah pembangun menambah 12 bulan dan berpendapat bahawa mereka telah menambah sepanjang tahun. Anda tidak boleh pasti bahawa semua bulan mengandungi kira-kira bilangan hari yang sama - dalam kalendar Koptik terdapat 12 bulan 30 hari, dan 1 bulan lima atau enam hari. Selain itu, anda tidak boleh pasti bahawa bilangan tahun hadapan akan lebih 1 daripada yang semasa, kerana dalam kalendar Jepun, tahun dikira daripada pengisytiharan maharaja seterusnya (dalam kes ini, walaupun 2 hari dalam bulan yang sama boleh tergolong dalam tahun yang berbeza). Satu-satunya cara untuk menulis kod berkualiti tinggi dan berfungsi yang berfungsi dengan beberapa kalendar sekaligus ialah teras kod anda, yang melaksanakan semua operasi pada tarikh dan masa, mesti ditulis menggunakan kalendar standard dan hanya apabila memasukkan/mengeluarkan tarikh sekiranya ia ditukar kepada sistem kalendar lain. Iaitu, disyorkan untuk menggunakan LocalDate untuk penyimpanan dan semua manipulasi tarikh dalam aplikasi anda. Dan hanya apabila menyetempatkan tarikh input dan output hendaklah anda menggunakan ChronoLocalDate , yang biasanya diperoleh daripada kelas kalendar yang disimpan dalam profil pengguna. Benar, kebanyakan aplikasi tidak memerlukan penyetempatan yang serius. Jika anda memerlukan penjelasan yang lebih terperinci tentang semua yang diterangkan dalam bab ini, selamat datang ke dokumentasi kelas ChronoLocalDate .      Sambungan artikel      Artikel asal
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION