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

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

JDK踩坑: Smart LocalDate

發(fā)布時(shí)間:2025/3/20 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JDK踩坑: Smart LocalDate 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
點(diǎn)擊上方?好好學(xué)java?,選擇?星標(biāo)?公眾號(hào)重磅資訊,干貨,第一時(shí)間送達(dá)今日推薦:分享一套基于SpringBoot和Vue的企業(yè)級(jí)中后臺(tái)開(kāi)源項(xiàng)目,這個(gè)項(xiàng)目有點(diǎn)哇塞!個(gè)人原創(chuàng)100W +訪(fǎng)問(wèn)量博客:點(diǎn)擊前往,查看更多

轉(zhuǎn)自:Telami,

鏈接:telami.cn/2020/smart_localdate/

前兩天線(xiàn)上出了個(gè)小問(wèn)題,有個(gè)統(tǒng)計(jì)頁(yè)面報(bào)錯(cuò)了。簡(jiǎn)單一看,原來(lái)是前端傳了個(gè)無(wú)效日期,2020-06-31。

代碼拋異常在這一行。

LocalDate.parse(param.getEndDate())

錯(cuò)誤信息如下:

java.time.format.DateTimeParseException: Text '2020-06-31' could not be parsed: Invalid date 'JUNE 31'

先不管為啥前端傳了個(gè)0631,為啥我這轉(zhuǎn)換日期會(huì)報(bào)錯(cuò)呢?已經(jīng)加了校驗(yàn)了啊。

public static final DateTimeFormatter dateTimeFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd"); public static boolean isDateTimeFormat2(String date) {String regex = "[0-9]{4}-[0-9]{2}-[0-9]{2}";Pattern pattern = Pattern.compile(regex);Matcher m = pattern.matcher(date);boolean dateFlag = m.matches();if (!dateFlag) {return false;} else {try {LocalDate.parse(date, dateTimeFormat);return true;} catch (DateTimeParseException var6) {return false;}} }

上面就是校驗(yàn)代碼,用了好久了,debug了一下,發(fā)現(xiàn)確實(shí)校驗(yàn)通過(guò)了。

嗯?等等,我明明傳的【2020-06-31】,怎么變成【2020-06-30】了,咋回事?

看看源碼吧。

/*** Obtains an instance of {@code LocalDate} from a text string such as {@code 2007-12-03}.* <p>* The string must represent a valid date and is parsed using* {@link java.time.format.DateTimeFormatter#ISO_LOCAL_DATE}.** @param text the text to parse such as "2007-12-03", not null* @return the parsed local date, not null* @throws DateTimeParseException if the text cannot be parsed*/ public static LocalDate parse(CharSequence text) {return parse(text, DateTimeFormatter.ISO_LOCAL_DATE); } /*** Obtains an instance of {@code LocalDate} from a text string using a specific formatter.* <p>* The text is parsed using the formatter, returning a date.** @param text the text to parse, not null* @param formatter the formatter to use, not null* @return the parsed local date, not null* @throws DateTimeParseException if the text cannot be parsed*/ public static LocalDate parse(CharSequence text, DateTimeFormatter formatter) {Objects.requireNonNull(formatter, "formatter");return formatter.parse(text, LocalDate::from); }

賣(mài)關(guān)子好累,不賣(mài)了。

LocalDate.parse 方法有兩個(gè),區(qū)別就是指沒(méi)指定 DateTimeFormatter。

很明顯上面的沒(méi)指定,下面那個(gè)指定了。

/*** Creates a formatter using the specified pattern.* <p>* This method will create a formatter based on a simple* <a href="#patterns">pattern of letters and symbols</a>* as described in the class documentation.* For example, {@code d MMM uuuu} will format 2011-12-03 as '3 Dec 2011'.* <p>* The formatter will use the {@link Locale#getDefault(Locale.Category) default FORMAT locale}.* This can be changed using {@link DateTimeFormatter#withLocale(Locale)} on the returned formatter* Alternatively use the {@link #ofPattern(String, Locale)} variant of this method.* <p>* The returned formatter has no override chronology or zone.* It uses {@link ResolverStyle#SMART SMART} resolver style.** @param pattern the pattern to use, not null* @return the formatter based on the pattern, not null* @throws IllegalArgumentException if the pattern is invalid* @see DateTimeFormatterBuilder#appendPattern(String)*/ public static DateTimeFormatter ofPattern(String pattern) {return new DateTimeFormatterBuilder().appendPattern(pattern).toFormatter(); }

劃重點(diǎn):

It uses {@link ResolverStyle#SMART SMART} resolver style.

SMART(聰明的,智能的),話(huà)說(shuō)我經(jīng)歷好幾個(gè)叫SMART的項(xiàng)目了……DateTimeFormatter.ofPattern,使用了智能解析模式。

public enum ResolverStyle {/*** Style to resolve dates and times strictly.* <p>* Using strict resolution will ensure that all parsed values are within* the outer range of valid values for the field. Individual fields may* be further processed for strictness.* <p>* For example, resolving year-month and day-of-month in the ISO calendar* system using strict mode will ensure that the day-of-month is valid* for the year-month, rejecting invalid values.*/STRICT,/*** Style to resolve dates and times in a smart, or intelligent, manner.* <p>* Using smart resolution will perform the sensible default for each* field, which may be the same as strict, the same as lenient, or a third* behavior. Individual fields will interpret this differently.* <p>* For example, resolving year-month and day-of-month in the ISO calendar* system using smart mode will ensure that the day-of-month is from* 1 to 31, converting any value beyond the last valid day-of-month to be* the last valid day-of-month.*/SMART,/*** Style to resolve dates and times leniently.* <p>* Using lenient resolution will resolve the values in an appropriate* lenient manner. Individual fields will interpret this differently.* <p>* For example, lenient mode allows the month in the ISO calendar system* to be outside the range 1 to 12.* For example, month 15 is treated as being 3 months after month 12.*/LENIENT; }

怎么個(gè)智能法呢?

1 to 31, converting any value beyond the last valid day-of-month to be the last valid day-of-month.

超出這個(gè)月的最后有效日,會(huì)被轉(zhuǎn)化為這個(gè)月的最后有效日。就是說(shuō) 31 就變成 30 了,但是 32 不會(huì),因?yàn)椴辉?1~31 之間。

現(xiàn)在我們知道了,為啥會(huì)開(kāi)篇所提的?2020-06-31?會(huì)通過(guò)了校驗(yàn),因?yàn)樗?SMART 模式。

public static final DateTimeFormatter ISO_LOCAL_DATE; static {ISO_LOCAL_DATE = new DateTimeFormatterBuilder().appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD).appendLiteral('-').appendValue(MONTH_OF_YEAR, 2).appendLiteral('-').appendValue(DAY_OF_MONTH, 2).toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE); }

而沒(méi)指定 DateTimeFormatter 的,則使用了默認(rèn)的 ISO_LOCAL_DATE。可以看出,它使用了 ResolverStyle.STRICT,嚴(yán)格模式。

到這里,就是全部真相了,看來(lái)JDK Smart與否,還得看使用者啊。

推薦文章
  • 今天給大家推薦6個(gè)Spring Boot項(xiàng)目,拿來(lái)就可以賺錢(qián)!

  • 分享一套基于SpringBoot和Vue的企業(yè)級(jí)中后臺(tái)開(kāi)源項(xiàng)目,這個(gè)項(xiàng)目有點(diǎn)哇塞!

  • 圈子哥推薦一種基于Spring Boot開(kāi)發(fā)OA開(kāi)源產(chǎn)品,學(xué)習(xí)/搞外快都是不二選擇!

  • 硬剛一周,3W字總結(jié),一年的經(jīng)驗(yàn)告訴你如何準(zhǔn)備校招!

原創(chuàng)電子書(shū)歷時(shí)整整一年總結(jié)的?Java面試+ Java入門(mén)技術(shù)學(xué)習(xí)指南,這是本人這幾年及校招的總結(jié),各種異步面試題已經(jīng)全部進(jìn)行總結(jié),按照章節(jié)復(fù)習(xí)即可,已經(jīng)拿到了了大廠(chǎng)提供。 原創(chuàng)思維導(dǎo)圖掃碼或者微信搜?程序員的技術(shù)圈子?回復(fù)?面試?領(lǐng)取原創(chuàng)電子書(shū)和思維導(dǎo)圖。

總結(jié)

以上是生活随笔為你收集整理的JDK踩坑: Smart LocalDate的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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