日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

4 种方法!检查字符串是否为合法的日期格式

發(fā)布時間:2025/3/11 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 4 种方法!检查字符串是否为合法的日期格式 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

哈嘍大家好,今天咱們來講一下,Java 中如何檢查一個字符串是否是合法的日期格式?

為什么要檢查時間格式?

后端接口在接收數(shù)據(jù)的時候,都需要進行檢查。檢查全部通過后,才能夠執(zhí)行業(yè)務邏輯。對于時間格式,我們一般需要檢查這么幾方面:

  • 字符串格式是否正確,比如格式是不是yyyy-MM-dd

  • 時間在合法范圍內(nèi),比如我們需要限定在一個月內(nèi)的時間

  • 字符串可以解析為正常的時間,比如 2 月 30 號就不是正常時間

  • 對于時間格式的判斷,我們可以通過正則表達式來檢查。不過考慮到正則表達式的性能、輸入數(shù)據(jù)的復雜性,一般能用別的方式,就不選正則表達式。我們還是選擇一種更加通用、更加高效的檢查方式。

    首先,定義時間校驗器的接口:

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

    接口方法接收一個字符串,返回布爾類型,表示字符串是否是合法的時間格式。

    實現(xiàn)方法

    接下來就是通過不同方式實現(xiàn)DateValidator。

    1.使用 DateFormat 檢查

    Java 提供了格式化和解析時間的工具:DateFormat抽象類和SimpleDataFormat實現(xiàn)類。我們借此實現(xiàn)時間校驗器:

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

    這里需要注意一下,DateFormat和SimpleDataFormat是非線程安全的,所以每次方法調(diào)用時,都需要新建實例。

    我們通過單元測試驗證下:

    class?DateValidatorUsingDateFormatTest?{@Testvoid?isValid()?{final?DateValidator?validator?=?new?DateValidatorUsingDateFormat("yyyy-MM-dd");Assertions.assertTrue(validator.isValid("2021-02-28"));Assertions.assertFalse(validator.isValid("2021-02-30"));} }

    在 Java8 之前,一般都是用這種方式來驗證。Java8 之后,我們有了更多的選擇。

    2.使用 LocalDate 檢查

    Java8 引入了更加好用日期和時間 API(想要了解更多內(nèi)容,請移步參看 Java8 中的時間類及常用 API)。其中包括LocalDate類,是一個不可變且線程安全的時間類。

    LocalDate提供了兩個靜態(tài)方法,用來解析時間。這兩個方法內(nèi)部都是使用java.time.format.DateTimeFormatter來處理數(shù)據(jù):

    //?使用?DateTimeFormatter.ISO_LOCAL_DATE?處理數(shù)據(jù) public?static?LocalDate?parse(CharSequence?text)?{return?parse(text,?DateTimeFormatter.ISO_LOCAL_DATE); }//?使用提供的?DateTimeFormatter?處理數(shù)據(jù) public?static?LocalDate?parse(CharSequence?text,?DateTimeFormatter?formatter)?{Objects.requireNonNull(formatter,?"formatter");return?formatter.parse(text,?LocalDate::from); }

    通過LocalDate的parse方法實現(xiàn)我們的校驗器:

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

    java.time.format.DateTimeFormatter類是不可變的,也就是天然的線程安全,我們可以在不同線程使用同一個校驗器實例。

    我們通過單元測試驗證下:

    class?DateValidatorUsingLocalDateTest?{@Testvoid?isValid()?{final?DateTimeFormatter?dateFormatter?=?DateTimeFormatter.ISO_LOCAL_DATE;final?DateValidator?validator?=?new?DateValidatorUsingLocalDate(dateFormatter);Assertions.assertTrue(validator.isValid("2021-02-28"));Assertions.assertFalse(validator.isValid("2021-02-30"));} }

    既然LocalDate#parse是通過DateTimeFormatter實現(xiàn)的,那我們也可以直接使用DateTimeFormatter。

    3.使用 DateTimeFormatter 檢查

    DateTimeFormatter解析文本總共分兩步。第一步,根據(jù)配置將文本解析為日期和時間字段;第二步,用解析后的字段創(chuàng)建日期和時間對象。

    實現(xiàn)驗證器:

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

    通過單元測試驗證:

    class?DateValidatorUsingDateTimeFormatterTest?{private?static?final?DateTimeFormatter?DATE_FORMATTER?=?DateTimeFormatter.ofPattern("uuuu-MM-dd",?Locale.CHINA);@Testvoid?isValid()?{final?DateTimeFormatter?dateFormatter?=?DATE_FORMATTER.withResolverStyle(ResolverStyle.STRICT);final?DateValidator?validator?=?new?DateValidatorUsingDateTimeFormatter(dateFormatter);Assertions.assertTrue(validator.isValid("2021-02-28"));Assertions.assertFalse(validator.isValid("2021-02-30"));} }

    可以看到,我們指定了轉(zhuǎn)換模式是ResolverStyle.STRICT,這個類型是說明解析模式。共有三種:

    • STRICT:嚴格模式,日期、時間必須完全正確。

    • SMART:智能模式,針對日可以自動調(diào)整。月的范圍在 1 到 12,日的范圍在 1 到 31。比如輸入是 2 月 30 號,當年 2 月只有 28 天,返回的日期就是 2 月 28 日。

    • LENIENT:寬松模式,主要針對月和日,會自動后延。結(jié)果類似于LocalData#plusDays或者LocalDate#plusMonths。

    我們通過例子看下區(qū)別:

    class?DateValidatorUsingDateTimeFormatterTest?{private?static?final?DateTimeFormatter?DATE_FORMATTER?=?DateTimeFormatter.ofPattern("uuuu-MM-dd",?Locale.CHINA);@Testvoid?testResolverStyle()?{Assertions.assertEquals(LocalDate.of(2021,?2,28),?parseDate("2021-02-28",?ResolverStyle.STRICT));Assertions.assertNull(parseDate("2021-02-29",?ResolverStyle.STRICT));Assertions.assertEquals(LocalDate.of(2021,?2,28),?parseDate("2021-02-28",?ResolverStyle.STRICT));Assertions.assertNull(parseDate("2021-13-28",?ResolverStyle.STRICT));Assertions.assertEquals(LocalDate.of(2021,?2,28),?parseDate("2021-02-28",?ResolverStyle.SMART));Assertions.assertEquals(LocalDate.of(2021,?2,28),?parseDate("2021-02-29",?ResolverStyle.SMART));Assertions.assertNull(parseDate("2021-13-28",?ResolverStyle.SMART));Assertions.assertNull(parseDate("2021-13-29",?ResolverStyle.SMART));Assertions.assertEquals(LocalDate.of(2021,?2,28),?parseDate("2021-02-28",?ResolverStyle.LENIENT));Assertions.assertEquals(LocalDate.of(2021,?3,1),?parseDate("2021-02-29",?ResolverStyle.LENIENT));Assertions.assertEquals(LocalDate.of(2022,?1,28),?parseDate("2021-13-28",?ResolverStyle.LENIENT));Assertions.assertEquals(LocalDate.of(2022,?2,2),?parseDate("2021-13-33",?ResolverStyle.LENIENT));}private?static?LocalDate?parseDate(String?dateString,?ResolverStyle?resolverStyle)?{try?{return?LocalDate.parse(dateString,?DATE_FORMATTER.withResolverStyle(resolverStyle));}?catch?(DateTimeParseException?e)?{return?null;}} }

    從例子可以看出,ResolverStyle.STRICT是嚴格控制,用來做時間校驗比較合適;ResolverStyle.LENIENT可以最大程度將字符串轉(zhuǎn)化為時間對象,在合理范圍內(nèi)可以隨便玩;ResolverStyle.SMART名為智能,但智力有限,兩不沾邊,優(yōu)勢不夠明顯。JDK 提供的DateTimeFormatter實現(xiàn),都是ResolverStyle.STRICT模式。

    說了 JDK 自帶的實現(xiàn),接下來說說第三方組件的實現(xiàn)方式。

    4.使用 Apache 出品的 commons-validator 檢查

    Apache Commons 項目提供了一個校驗器框架,包含多種校驗規(guī)則,包括日期、時間、數(shù)字、貨幣、IP 地址、郵箱、URL 地址等。本文主要說檢查時間,所以重點看看GenericValidator類提供的isDate方法:

    public?class?GenericValidator?implements?Serializable?{//?其他方法public?static?boolean?isDate(String?value,?Locale?locale)?{return?DateValidator.getInstance().isValid(value,?locale);}public?static?boolean?isDate(String?value,?String?datePattern,?boolean?strict)?{return?org.apache.commons.validator.DateValidator.getInstance().isValid(value,?datePattern,?strict);} }

    先引入依賴:

    <dependency><groupId>commons-validator</groupId><artifactId>commons-validator</artifactId><version>1.7</version> </dependency>

    實現(xiàn)驗證器:

    public?class?DateValidatorUsingCommonsValidator?implements?DateValidator?{private?final?String?dateFormat;public?DateValidatorUsingCommonsValidator(String?dateFormat)?{this.dateFormat?=?dateFormat;}@Overridepublic?boolean?isValid(String?dateStr)?{return?GenericValidator.isDate(dateStr,?dateFormat,?true);} }

    通過單元測試驗證:

    class?DateValidatorUsingCommonsValidatorTest?{@Testvoid?isValid()?{final?DateValidator?dateValidator?=?new?DateValidatorUsingCommonsValidator("yyyy-MM-dd");Assertions.assertTrue(dateValidator.isValid("2021-02-28"));Assertions.assertFalse(dateValidator.isValid("2021-02-30"));} }

    看org.apache.commons.validator.DateValidator#isValid源碼可以發(fā)現(xiàn),內(nèi)部是通過DateFormat和SimpleDateFormat實現(xiàn)的。

    總結(jié)

    在本文中,我們通過四種方式實現(xiàn)了時間字符串校驗邏輯。其中DateFormat和SimpleDataFormat是非線程安全的,所以每次方法調(diào)用時,都需要新建實例;通過觀察apache.commons.validator.DateValidator#isValid的源碼發(fā)現(xiàn),它的內(nèi)部也是通過DateFormat和SimpleDateFormat實現(xiàn)的;而LocalDate和DateTimeFormatter則為JDK8中提供的實現(xiàn)方法。

    推薦閱讀

    SpringBoot時間格式化的5種方法!

    3種時間格式化的方法,SpringBoot篇!

    SpringBoot官方熱部署和遠程調(diào)試神器,真帶勁!


    總結(jié)

    以上是生活随笔為你收集整理的4 种方法!检查字符串是否为合法的日期格式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。