Berhijrah ke API Tarikh Masa 8 Java Baru

1. Gambaran keseluruhan

Dalam tutorial ini, anda akan belajar bagaimana membuat refactor kod anda untuk memanfaatkan API Date Time baru yang diperkenalkan di Java 8.

2. API Baru Sekilas

Bekerja dengan kurma di Jawa dulu memang sukar. Perpustakaan tarikh lama yang disediakan oleh JDK hanya merangkumi tiga kelas: java.util.Date, java.util.Calendar dan java.util.Timezone .

Ini hanya sesuai untuk tugas yang paling asas. Untuk apa sahaja yang jauh dari kompleks, para pembangun harus menggunakan perpustakaan pihak ketiga atau menulis banyak kod tersuai.

Java 8 memperkenalkan API Tarikh Masa yang sama sekali baru ( java.util.time. * ) Yang secara longgar berdasarkan perpustakaan Java yang popular yang disebut JodaTime. API baru ini mempermudah pemprosesan tarikh dan masa secara dramatik dan memperbaiki banyak kekurangan perpustakaan tarikh lama.

1.1. Kejelasan API

Kelebihan pertama API baru adalah kejelasan - API sangat jelas, ringkas dan mudah difahami. Tidak terdapat banyak ketidakkonsistenan yang terdapat di perpustakaan lama seperti penomoran medan (dalam bulan Kalendar adalah berdasarkan sifar, tetapi hari dalam seminggu adalah berdasarkan satu).

1.2. Kelenturan API

Kelebihan lain ialah fleksibiliti - bekerja dengan banyak perwakilan masa . Perpustakaan tarikh lama hanya merangkumi kelas perwakilan satu masa - java.util . Tarikh , yang walaupun namanya, sebenarnya merupakan cap waktu. Ia hanya menyimpan bilangan milisaat yang berlalu sejak zaman Unix.

API baru mempunyai banyak perwakilan masa yang berbeza, masing-masing sesuai untuk kes penggunaan yang berbeza:

  • Sekejap - mewakili titik waktu (cap waktu)
  • LocalDate - mewakili tarikh (tahun, bulan, hari)
  • LocalDateTime - sama dengan LocalDate , tetapi merangkumi masa dengan ketepatan nanodetik
  • OffsetDateTime - sama dengan LocalDateTime , tetapi dengan zon waktu mengimbangi
  • LocalTime - masa dengan ketepatan nanodetik dan tanpa maklumat tarikh
  • ZonedDateTime - sama dengan OffsetDateTime , tetapi merangkumi ID zon waktu
  • OffsetLocalTime - sama dengan LocalTime , tetapi dengan zon waktu mengimbangi
  • MonthDay - bulan dan hari, tanpa tahun atau masa
  • BulanBulan - bulan dan tahun, tanpa hari atau masa
  • Tempoh - jumlah masa yang dinyatakan dalam beberapa saat, minit dan jam. Mempunyai ketepatan nanodetik
  • Tempoh - jumlah masa yang dinyatakan dalam hari, bulan dan tahun

1.3. Ketahanan dan Keselamatan Benang

Kelebihan lain adalah bahawa perwakilan sepanjang masa di Java 8 Date Time API tidak dapat diubah dan dengan demikian selamat untuk utas.

Semua kaedah mutasi mengembalikan salinan baru dan bukannya mengubah keadaan objek asal.

Kelas lama seperti java.util.Date tidak selamat dari benang dan boleh memperkenalkan pepijat serentak yang sangat halus.

1.4. Kaedah Berantai

Semua kaedah mutasi dapat dirantai bersama, memungkinkan untuk melaksanakan transformasi kompleks dalam satu baris kod.

ZonedDateTime nextFriday = LocalDateTime.now() .plusHours(1) .with(TemporalAdjusters.next(DayOfWeek.FRIDAY)) .atZone(ZoneId.of("PST")); 

2. Contohnya

Contoh di bawah akan menunjukkan cara melaksanakan tugas biasa dengan API lama dan baru.

Mendapat masa semasa

// Old Date now = new Date(); // New ZonedDateTime now = ZonedDateTime.now(); 

Mewakili masa tertentu

// Old Date birthDay = new GregorianCalendar(1990, Calendar.DECEMBER, 15).getTime(); // New LocalDate birthDay = LocalDate.of(1990, Month.DECEMBER, 15); 

Mengekstrak bidang tertentu

// Old int month = new GregorianCalendar().get(Calendar.MONTH); // New Month month = LocalDateTime.now().getMonth(); 

Menambah dan mengurangkan masa

// Old GregorianCalendar calendar = new GregorianCalendar(); calendar.add(Calendar.HOUR_OF_DAY, -5); Date fiveHoursBefore = calendar.getTime(); // New LocalDateTime fiveHoursBefore = LocalDateTime.now().minusHours(5); 

Mengubah bidang tertentu

// Old GregorianCalendar calendar = new GregorianCalendar(); calendar.set(Calendar.MONTH, Calendar.JUNE); Date inJune = calendar.getTime(); // New LocalDateTime inJune = LocalDateTime.now().withMonth(Month.JUNE.getValue()); 

Memotong

Pemotongan mengatur semula semua medan masa lebih kecil daripada bidang yang ditentukan. Dalam contoh minit di bawah dan semua perkara di bawah akan ditetapkan ke sifar

// Old Calendar now = Calendar.getInstance(); now.set(Calendar.MINUTE, 0); now.set(Calendar.SECOND, 0); now.set(Calendar.MILLISECOND, 0); Date truncated = now.getTime(); // New LocalTime truncated = LocalTime.now().truncatedTo(ChronoUnit.HOURS); 

Penukaran zon waktu

// Old GregorianCalendar calendar = new GregorianCalendar(); calendar.setTimeZone(TimeZone.getTimeZone("CET")); Date centralEastern = calendar.getTime(); // New ZonedDateTime centralEastern = LocalDateTime.now().atZone(ZoneId.of("CET")); 

Mendapat jangka masa antara dua titik dalam masa

// Old GregorianCalendar calendar = new GregorianCalendar(); Date now = new Date(); calendar.add(Calendar.HOUR, 1); Date hourLater = calendar.getTime(); long elapsed = hourLater.getTime() - now.getTime(); // New LocalDateTime now = LocalDateTime.now(); LocalDateTime hourLater = LocalDateTime.now().plusHours(1); Duration span = Duration.between(now, hourLater); 

Pemformatan dan penghuraian masa

DateTimeFormatter adalah pengganti SimpleDateFormat lama yang selamat untuk thread dan memberikan fungsi tambahan.

// Old SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); Date now = new Date(); String formattedDate = dateFormat.format(now); Date parsedDate = dateFormat.parse(formattedDate); // New LocalDate now = LocalDate.now(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); String formattedDate = now.format(formatter); LocalDate parsedDate = LocalDate.parse(formattedDate, formatter); 

Bilangan hari dalam sebulan

// Old Calendar calendar = new GregorianCalendar(1990, Calendar.FEBRUARY, 20); int daysInMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH); // New int daysInMonth = YearMonth.of(1990, 2).lengthOfMonth();

3. Berinteraksi Dengan Kod Warisan

Dalam banyak kes, pengguna mungkin perlu memastikan interoperabilitas dengan perpustakaan pihak ketiga yang bergantung pada perpustakaan tarikh lama.

Di Java 8 kelas perpustakaan tarikh lama telah diperluas dengan kaedah yang mengubahnya menjadi objek yang sesuai dari API Tarikh baru.

Kelas baru memberikan fungsi yang serupa.

Instant instantFromCalendar = GregorianCalendar.getInstance().toInstant(); ZonedDateTime zonedDateTimeFromCalendar = new GregorianCalendar().toZonedDateTime(); Date dateFromInstant = Date.from(Instant.now()); GregorianCalendar calendarFromZonedDateTime = GregorianCalendar.from(ZonedDateTime.now()); Instant instantFromDate = new Date().toInstant(); ZoneId zoneIdFromTimeZone = TimeZone.getTimeZone("PST").toZoneId(); 

4. Kesimpulan

Dalam artikel ini, kami meneroka API Waktu Tarikh baru yang tersedia di Java 8. Kami melihat kelebihannya, dibandingkan dengan API yang tidak digunakan lagi dan menunjukkan perbezaan menggunakan beberapa contoh.

Perhatikan bahawa kami hampir tidak menggaru permukaan API Date Time yang baru. Pastikan membaca dokumentasi rasmi untuk mengetahui pelbagai alat yang ditawarkan oleh API baru.

Contoh kod boleh didapati dalam projek GitHub.