Periksa Jika String Adalah Tanggal yang Valid di Java

1. Perkenalan

Dalam tutorial ini, kita akan membahas berbagai cara untuk memeriksa apakah sebuah String berisi tanggal yang valid di Java.

Kami akan membahas solusi sebelum Java 8, setelah Java 8, dan menggunakan Apache Commons Validator.

2. Ikhtisar Validasi Tanggal

Setiap kali kami menerima data dalam aplikasi apa pun, kami perlu memverifikasi keabsahannya sebelum melakukan pemrosesan lebih lanjut.

Dalam kasus input tanggal, kami mungkin perlu memverifikasi yang berikut:

  • Masukan berisi tanggal dalam format yang valid, seperti MM / DD / YYYY
  • Berbagai bagian masukan berada dalam kisaran yang valid
  • Masukan memutuskan ke tanggal yang valid di kalender

Kita dapat menggunakan ekspresi reguler untuk melakukan hal di atas. Namun, ekspresi reguler untuk menangani berbagai format input dan lokal itu rumit dan rawan kesalahan. Selain itu, hal tersebut dapat menurunkan kinerja.

Kami akan membahas berbagai cara untuk menerapkan validasi tanggal dengan cara yang fleksibel, kuat, dan efisien.

Pertama, mari tulis antarmuka untuk validasi tanggal:

public interface DateValidator { boolean isValid(String dateStr); }

Di bagian selanjutnya, kami akan mengimplementasikan antarmuka ini menggunakan berbagai pendekatan.

3. Validasi Menggunakan DateFormat

Java telah menyediakan fasilitas untuk memformat dan mengurai tanggal sejak awal. Fungsionalitas ini ada dalam kelas abstrak DateFormat dan implementasinya - SimpleDateFormat .

Mari mengimplementasikan validasi tanggal menggunakan metode parse dari kelas DateFormat :

public class DateValidatorUsingDateFormat implements DateValidator { private String dateFormat; public DateValidatorUsingDateFormat(String dateFormat) { this.dateFormat = dateFormat; } @Override public boolean isValid(String dateStr) { DateFormat sdf = new SimpleDateFormat(this.dateFormat); sdf.setLenient(false); try { sdf.parse(dateStr); } catch (ParseException e) { return false; } return true; } }

Karena itu DateFormat dan kelas terkait tidak thread-safe , kami menciptakan sebuah contoh baru untuk setiap metode panggilan.

Selanjutnya, mari tulis pengujian unit untuk kelas ini:

DateValidator validator = new DateValidatorUsingDateFormat("MM/dd/yyyy"); assertTrue(validator.isValid("02/28/2019")); assertFalse(validator.isValid("02/30/2019"));

Ini telah menjadi solusi paling umum sebelum Java 8.

4. Validasi Menggunakan LocalDate

Java 8 memperkenalkan API Tanggal dan Waktu yang ditingkatkan. Itu menambahkan kelas LocalDate , yang mewakili tanggal tanpa waktu. Kelas ini tidak dapat diubah dan aman untuk thread.

LocalDate menyediakan dua metode statis untuk mengurai tanggal. Keduanya menggunakan DateTimeFormatter untuk melakukan parsing sebenarnya:

public static LocalDate parse​(CharSequence text) // parses dates using using DateTimeFormatter.ISO_LOCAL_DATE public static LocalDate parse​(CharSequence text, DateTimeFormatter formatter) // parses dates using the provided formatter

Mari gunakan metode parse untuk mengimplementasikan validasi tanggal:

public class DateValidatorUsingLocalDate implements DateValidator { private DateTimeFormatter dateFormatter; public DateValidatorUsingLocalDate(DateTimeFormatter dateFormatter) { this.dateFormatter = dateFormatter; } @Override public boolean isValid(String dateStr) { try { LocalDate.parse(dateStr, this.dateFormatter); } catch (DateTimeParseException e) { return false; } return true; } }

Implementasinya menggunakan objek DateTimeFormatter untuk pemformatan. Karena kelas ini aman untuk thread, kami menggunakan instance yang sama di berbagai panggilan metode.

Mari juga tambahkan pengujian unit untuk implementasi ini:

DateTimeFormatter dateFormatter = DateTimeFormatter.BASIC_ISO_DATE; DateValidator validator = new DateValidatorUsingLocalDate(dateFormatter); assertTrue(validator.isValid("20190228")); assertFalse(validator.isValid("20190230"));

5. Validasi Menggunakan DateTimeFormatter

Di bagian sebelumnya, kita melihat bahwa LocalDate menggunakan objek DateTimeFormatter untuk parsing. Kita juga bisa menggunakan kelas DateTimeFormatter secara langsung untuk pemformatan dan penguraian.

DateTimeFormatter mengurai teks dalam dua fase. Pada Tahap 1, ini mengurai teks menjadi berbagai bidang tanggal dan waktu berdasarkan konfigurasi. Dalam Tahap 2, ini menyelesaikan bidang yang diurai menjadi objek tanggal dan / atau waktu.

The ResolverStyle fase kontrol atribut 2. Ini adalah enum memiliki tiga nilai yang mungkin:

  • LENIENT - menyelesaikan tanggal dan waktu dengan lembut
  • SMART - menyelesaikan tanggal dan waktu dengan cara yang cerdas
  • STRICT - menetapkan tanggal dan waktu dengan ketat

Sekarang, mari tulis validasi tanggal menggunakan DateTimeFormatter secara langsung:

public class DateValidatorUsingDateTimeFormatter implements DateValidator { private DateTimeFormatter dateFormatter; public DateValidatorUsingDateTimeFormatter(DateTimeFormatter dateFormatter) { this.dateFormatter = dateFormatter; } @Override public boolean isValid(String dateStr) { try { this.dateFormatter.parse(dateStr); } catch (DateTimeParseException e) { return false; } return true; } }

Selanjutnya, mari tambahkan pengujian unit untuk kelas ini:

DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("uuuu-MM-dd", Locale.US) .withResolverStyle(ResolverStyle.STRICT); DateValidator validator = new DateValidatorUsingDateTimeFormatter(dateFormatter); assertTrue(validator.isValid("2019-02-28")); assertFalse(validator.isValid("2019-02-30"));

Dalam pengujian di atas, kami membuat DateTimeFormatter berdasarkan pola dan lokal. Kami menggunakan resolusi ketat untuk tanggal.

6. Validasi Menggunakan Validator Apache Commons

Proyek Apache Commons menyediakan kerangka validasi. Ini berisi rutinitas validasi, seperti tanggal, waktu, angka, mata uang, alamat IP, email, dan URL.

Untuk tujuan kita di artikel ini, mari kita lihat kelas GenericValidator , yang menyediakan beberapa metode untuk memeriksa apakah sebuah String berisi tanggal yang valid:

public static boolean isDate(String value, Locale locale) public static boolean isDate(String value,String datePattern, boolean strict)

Untuk menggunakan perpustakaan, mari tambahkan dependensi Maven validator-commons ke proyek kita:

 commons-validator commons-validator 1.6 

Selanjutnya, mari gunakan kelas GenericValidator untuk memvalidasi tanggal:

assertTrue(GenericValidator.isDate("2019-02-28", "yyyy-MM-dd", true)); assertFalse(GenericValidator.isDate("2019-02-29", "yyyy-MM-dd", true));

7. Kesimpulan

Pada artikel ini, kami melihat berbagai cara untuk memeriksa apakah sebuah String berisi tanggal yang valid.

Seperti biasa, kode sumber lengkap dapat ditemukan di GitHub.