Periksa Jika Rentetan Adalah Tarikh Sah di Java

1. Pengenalan

Dalam tutorial ini, kita akan membincangkan pelbagai cara untuk memeriksa apakah String mengandungi tarikh yang sah di Java.

Kami akan membincangkan penyelesaiannya sebelum Java 8, setelah Java 8, dan menggunakan Validator Apache Commons.

2. Gambaran Keseluruhan Pengesahan Tarikh

Setiap kali kami menerima data dalam aplikasi apa pun, kami perlu mengesahkan bahawa ia sah sebelum melakukan pemprosesan lebih lanjut.

Sekiranya input tarikh, kami mungkin perlu mengesahkan perkara berikut:

  • Input mengandungi tarikh dalam format yang sah, seperti MM / DD / YYYY
  • Pelbagai bahagian input berada dalam julat yang sah
  • Input akan ditetapkan ke tarikh yang sah dalam kalendar

Kita boleh menggunakan ungkapan biasa untuk melakukan perkara di atas. Walau bagaimanapun, ungkapan biasa untuk menangani pelbagai format input dan lokasi adalah rumit dan ralat. Di samping itu, mereka dapat menurunkan prestasi.

Kami akan membincangkan pelbagai cara untuk melaksanakan pengesahan tarikh dengan cara yang fleksibel, mantap dan cekap.

Pertama, mari kita tulis antara muka untuk pengesahan tarikh:

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

Pada bahagian seterusnya, kami akan melaksanakan antara muka ini menggunakan pelbagai pendekatan.

3. Mengesahkan Menggunakan DateFormat

Java telah menyediakan kemudahan untuk memformat dan menguraikan tarikh sejak awal. Fungsi ini akan dateformat kelas abstrak dan pelaksanaannya - SimpleDateFormat .

Mari kita laksanakan pengesahan tarikh menggunakan kaedah menguraikan 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; } }

Oleh kerana DateFormat dan kelas yang berkaitan tidak selamat untuk thread , kami membuat contoh baru untuk setiap kaedah panggilan.

Seterusnya, mari kita tulis ujian unit untuk kelas ini:

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

Ini adalah penyelesaian yang paling biasa sebelum Java 8.

4. Mengesahkan Menggunakan Tempatan Tempatan

Java 8 memperkenalkan API Tarikh dan Waktu yang lebih baik. Ia menambah kelas LocalDate , yang mewakili tarikh tanpa masa. Kelas ini tidak berubah dan selamat di benang.

LocalDate menyediakan dua kaedah statik untuk menguraikan tarikh. Kedua-dua mereka menggunakan DateTimeFormatter untuk melakukan penghuraian sebenar:

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 kaedah parse untuk melaksanakan pengesahan tarikh:

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; } }

Pelaksanaannya menggunakan objek DateTimeFormatter untuk pemformatan. Oleh kerana kelas ini selamat digunakan, kami menggunakan contoh yang sama untuk panggilan kaedah yang berbeza.

Mari juga tambahkan ujian unit untuk pelaksanaan ini:

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

5. Mengesahkan Menggunakan DateTimeFormatter

Pada bahagian sebelumnya, kami melihat bahawa LocalDate menggunakan objek DateTimeFormatter untuk dihuraikan. Kita juga boleh menggunakan kelas DateTimeFormatter secara langsung untuk memformat dan menghuraikan.

DateTimeFormatter menguraikan teks dalam dua fasa. Pada Tahap 1, teks menguraikan teks ke dalam pelbagai bidang tarikh dan waktu berdasarkan konfigurasi. Pada Tahap 2, bidang ini mengubah bidang yang dihurai menjadi objek tarikh dan / atau waktu.

The ResolverStyle kawalan atribut fasa 2. Ia adalah satu enum mempunyai tiga nilai yang mungkin:

  • LENIENT - menyelesaikan tarikh dan masa dengan santai
  • SMART - menyelesaikan tarikh dan masa dengan cara yang bijak
  • KEKUATAN - menyelesaikan tarikh dan masa dengan ketat

Sekarang, mari kita tulis pengesahan tarikh 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; } }

Seterusnya, mari tambah ujian 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 ujian di atas, kami membuat DateTimeFormatter berdasarkan corak dan tempat. Kami menggunakan ketetapan yang ketat untuk tarikh.

6. Mengesahkan Menggunakan Validator Apache Commons

Projek Apache Commons menyediakan rangka pengesahan. Ini berisi rutin pengesahan, seperti tanggal, waktu, angka, mata wang, alamat IP, e-mel, dan URL.

Untuk tujuan kami dalam artikel ini, mari kita lihat kelas GenericValidator , yang menyediakan beberapa kaedah untuk memeriksa sama ada String mengandungi tarikh yang sah:

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

Untuk menggunakan perpustakaan, mari tambahkan kebergantungan commons-validator Maven ke projek kami:

 commons-validator commons-validator 1.6 

Seterusnya, mari kita gunakan kelas GenericValidator untuk mengesahkan tarikh:

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

7. Kesimpulannya

Dalam artikel ini, kami melihat pelbagai cara untuk memeriksa apakah String mengandungi tarikh yang sah.

Seperti biasa, kod sumber lengkap boleh didapati di GitHub.