点击上方 好好学java ,选择 星标 公众号重磅资讯,干货,第一时间送达今日推荐:分享一套基于SpringBoot和Vue的企业级中后台开源项目,这个项目有点哇塞!个人原创100W +访问量博客:点击前往,查看更多

转自:Telami,

链接:telami.cn/2020/smart_localdate/

前两天线上出了个小问题,有个统计页面报错了。简单一看,原来是前端传了个无效日期,2020-06-31

代码抛异常在这一行。

LocalDate.parse(param.getEndDate())

错误信息如下:

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

先不管为啥前端传了个0631,为啥我这转换日期会报错呢?已经加了校验了啊。

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

上面就是校验代码,用了好久了,debug了一下,发现确实校验通过了。

嗯?等等,我明明传的【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);
}

卖关子好累,不卖了。

LocalDate.parse 方法有两个,区别就是指没指定 DateTimeFormatter。

很明显上面的没指定,下面那个指定了。

/*** 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();
}

划重点:

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

SMART(聪明的,智能的),话说我经历好几个叫SMART的项目了……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;
}

怎么个智能法呢?

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

超出这个月的最后有效日,会被转化为这个月的最后有效日。就是说 31 就变成 30 了,但是 32 不会,因为不在 1~31 之间。

现在我们知道了,为啥会开篇所提的 2020-06-31 会通过了校验,因为它是 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);
}

而没指定 DateTimeFormatter 的,则使用了默认的 ISO_LOCAL_DATE。可以看出,它使用了 ResolverStyle.STRICT,严格模式。

到这里,就是全部真相了,看来JDK Smart与否,还得看使用者啊。

推荐文章
  • 今天给大家推荐6个Spring Boot项目,拿来就可以赚钱!

  • 分享一套基于SpringBoot和Vue的企业级中后台开源项目,这个项目有点哇塞!

  • 圈子哥推荐一种基于Spring Boot开发OA开源产品,学习/搞外快都是不二选择!

  • 硬刚一周,3W字总结,一年的经验告诉你如何准备校招!

原创电子书历时整整一年总结的 Java面试+ Java入门技术学习指南,这是本人这几年及校招的总结,各种异步面试题已经全部进行总结,按照章节复习即可,已经拿到了了大厂提供。
原创思维导图扫码或者微信搜 程序员的技术圈子 回复 面试 领取原创电子书和思维导图。

JDK踩坑: Smart LocalDate相关推荐

  1. java调用clang编译的so_写Java这么久,JDK源码编译过没?编译JDK源码踩坑纪实

    好奇害死羊 很多小伙伴们做Java开发,天天写Java代码,肯定离不开Java基础环境:JDK,毕竟我们写好的Java代码也是跑在JVM虚拟机上. 一般来说,我们学Java之前,第一步就是安装JDK环 ...

  2. 写Java这么久,JDK源码编译过没?编译JDK源码踩坑纪实

    好奇害死羊 很多小伙伴们做Java开发,天天写Java代码,肯定离不开Java基础环境:JDK,毕竟我们写好的Java代码也是跑在JVM虚拟机上. 一般来说,我们学Java之前,第一步就是安装JDK环 ...

  3. 【问题解决】Android JDK版本不匹配导致崩溃踩坑记录

    [问题解决]Android JDK版本不匹配导致崩溃踩坑记录 部分机型反馈崩溃问题 谷歌回复与解决方案 Android打包脱糖操作 对比与排查 总结 前几天同事遇到一个非常诡异的报错,紧急处理后,趁着 ...

  4. 谷粒商城开发踩坑及部分知识点大总结

    谷粒商城开发BUG踩坑及部分知识点大总结 基本上bug的出现位置和时间线都能够匹配 如果对你有帮助的话就点个赞哈 2022.6.28 github设置ssh免密登陆,以下代码在git bash上面输入 ...

  5. restTemplate使用和踩坑总结

    日常工作中肯定会遇到服务之间的调用,尤其是现在都是微服务的架构,所以总结一下restTemplate的最常用的用法以及自己踩过的坑. restTemplate的使用 restTemplate底层调用的 ...

  6. sonar覆盖率怎么统计的_实战|Java 测试覆盖率 Jacoco插桩的不同形式总结和踩坑记录(上)...

    本文为霍格沃兹测试学院优秀学员关于 Jacoco 的小结和踩坑记录.测试开发进阶学习,文末加群. 一.概述 测试覆盖率是老生常谈的话题.因为我测试理论基础不是很好,这里就不提需求.覆盖率等内容,直奔主 ...

  7. 日常踩坑记录-汇总版

    开发踩坑记录,不定时更新 心得 RTFM 严谨的去思考问题,处理问题 严格要求自己的代码编写习惯与风格 注意 单词拼写 20200207 mybatis plus 自带insert插入异常 sql i ...

  8. 记录seata初踩坑

    这里写自定义目录标题 最近在跟着尚硅谷的视频自学seata,也是踩坑不断,话不多说,还是直接上问题吧. 环境介绍-- 系统:Windows,没用Linux,想着Windows环境都整不明白,还用啥Li ...

  9. 【Java笔记+踩坑】SpringBoot基础3——开发。热部署+配置高级+整合NoSQL/缓存/任务/邮件/监控

      导航: [黑马Java笔记+踩坑汇总]JavaSE+JavaWeb+SSM+SpringBoot+瑞吉外卖+SpringCloud/SpringCloudAlibaba+黑马旅游+谷粒商城 目录 ...

最新文章

  1. 谁干的mysql无密码登录?
  2. 解决sharepoint2010的多行文本框的插入图片—【从sharepoint】的disabled问题
  3. python二进制文件的读取与写入可以分别使用什么方法_用python实现读写文件常见操作方式...
  4. 命令行下安装的tensorflow怎么打开_CourseMaker微课制作教程18:录ppt一直“正在打开……”及WPS下ppt满屏放映怎么办?...
  5. Visual Studio 2022 预览版2 发布啦
  6. [css] 怎样去除图片自带的边距?
  7. matlab 小波中心频率,小波频域特性Matlab实现.pdf
  8. Office 365系列之八:配置和体验Exchange和Lync
  9. 误差理论实际应用公式
  10. tensorflow之读取jpg图像保存为tfrecord再读取
  11. 相机标定后图像像素和物理尺寸对应_你需要事件相机标定板,咱做了个
  12. Hibernate教程——我的笔记
  13. K3 WISE,销售订单新增批号并能携带至销售出库单
  14. 数学建模与数学实验 (MATLAB)
  15. mysql性能分析工具_MySQL性能分析、及调优工具使用详解
  16. R语言--异常值检测
  17. 今天来看一下云测平台的测试实验
  18. Navigation Bar的背景图片设置
  19. Sympy符号计算(使用python求导,解方程组)
  20. 罗克韦尔AB PLC RSLogix数字量IO模块基本介绍

热门文章

  1. uboot重定位代码分析(转)
  2. spring + mina 作为客户端解析H2协议的使用总结
  3. 使用Aspose.Cell控件实现Excel高难度报表的生成(三)
  4. C++ Primer 5th笔记(chap 17 标准库特殊设施)匹配标志
  5. 初等数论--同余方程--同余方程运算:模逆运算,模指数运算
  6. [密码学] RSA利用解密指数分解n
  7. buu rsarsa
  8. python_函数相关的各种参数定义和传递
  9. [architecture]-ARM AMBA/AXI/ACE/LITE总线介绍
  10. 博客笔记导读目录-temp