大厂都是怎么用Java8代替SimpleDateFormat?(上)

简介: 大厂都是怎么用Java8代替SimpleDateFormat?

1 SimpleDateFormat 之坑

1.1 格式化

1.1.1 案例

  • 初始化一个Calendar,设置日期2020年12月29日
  • image.png
  • 日志
  • image.png
  • 这是由于混淆SimpleDateFormat的各种格式化模式:
  • 小写y是年
  • 大写Y是week year,即所在的周属于哪一年

一年第一周的判断方式

从getFirstDayOfWeek()开始,完整的7天,并且包含那一年至少getMinimalDaysInFirstWeek()天。

该计算方式和区域相关,对zh_CN区域,2020年第一周条件:从周日开始的完整7天,2020年包含1天即 可。显然,2019年12月27日周日到2020年1月2日周六是2020年第一周,得出的week year就是2021年。


若把区域改为法国

Locale.setDefault(Locale.FRANCE);

则week yeay就还是2020年,因为一周的第一天从周一开始算,2020年的第一周是2019年12月28日周一开始,27日还是属于去年:

image.png

小结

无特殊需求,针对年份的日期格式化,应该一律使用 “y” 而非 “Y”。

线程安全问题

使用一个100线程的线程池,循环20次把时间格式化任务提交到线程池处理,每个任务中又循环10次解析2020-01-01 11:12:13这样一个时间表示:

  • 运行程序后大量报错,即使没有报错的输出结果也不正常,比如2020年解析成57728年
  • 9.png
  • SimpleDateFormat 用于定义解析和格式化日期时间的模式。看起来是一次性工作,应该复用,但它的解析和格式化操作都非线程安全。

分析源码

10.png

SimpleDateFormat继承自DateFormatDateFormat有字段Calendar

  • SimpleDateFormat#parse调用CalendarBuilder#establish构建Calendar
  • image.png
  • establish方法内部先清空Calendar再构建Calendar,整个操作没有加锁。
  • 11.png
  • 显然,若使用线程池调用parse,即多线程并发操作一个Calendar,就可能会产生一个线程还没来得及处理Calendar就被另一个线程清空。format方法同理,不再赘述。因此只能在同一个线程复用SimpleDateFormat,


解决方案

通过ThreadLocal来存放SimpleDateFormat:


日志输出全部正确

12.png

1.2 当需要解析的字符串和格式不匹配,SimpleDateFormat还是能得到结果

案例

使用yyyyMM解析20160901字符串:

image.png

居然输出2112年,这是因为把 1111当成月份

image.png

对于SimpleDateFormat的这些坑,使用Java 8中的DateTimeFormatter即可避免。

目录
相关文章
|
4月前
|
Java
【零基础学Java】—Java 日期时间(三十二)
【零基础学Java】—Java 日期时间(三十二)
|
4月前
|
Java
【零基础学Java】—Java 日期时间(三十一)
【零基础学Java】—Java 日期时间(三十一)
|
6月前
|
存储 安全 Java
Java在工作当中经常使用的常用类
Java在工作当中经常使用的常用类
37 0
java202302java学习笔记第十五天-字符串相关类的底层原理4
java202302java学习笔记第十五天-字符串相关类的底层原理4
38 0
java202302java学习笔记第十五天-字符串相关类的底层原理4
java202302java学习笔记第十五天-字符串相关类的底层原理1
java202302java学习笔记第十五天-字符串相关类的底层原理1
43 0
java202302java学习笔记第十五天-字符串相关类的底层原理1
java202302java学习笔记第十五天-字符串相关类的底层原理2
java202302java学习笔记第十五天-字符串相关类的底层原理2
43 0
java202302java学习笔记第十五天-字符串相关类的底层原理2
java202302java学习笔记第十五天-字符串相关类的底层原理5
java202302java学习笔记第十五天-字符串相关类的底层原理5
36 0
java202302java学习笔记第十五天-字符串相关类的底层原理5
java202302java学习笔记第十五天-字符串相关类的底层原理3
java202302java学习笔记第十五天-字符串相关类的底层原理3
48 0
java202302java学习笔记第十五天-字符串相关类的底层原理3
|
Java
java学习第一天笔记-java基础概念04-字面量2-基本用法21
java学习第一天笔记-java基础概念04-字面量2-基本用法21
50 0
java学习第一天笔记-java基础概念04-字面量2-基本用法21
|
Java
java学习第一天笔记-java基础概念03-字面量2-20
java学习第一天笔记-java基础概念03-字面量2-20
41 0
java学习第一天笔记-java基础概念03-字面量2-20