天天看点

大厂日期时间处理最佳实践(上)1 背景2 初始化日期时间

1 背景

Java8前,处理日期时间时,使用的“三大件”

  • Date
  • Calender
  • SimpleDateFormat

以声明时间戳、使用日历处理日期和格式化解析日期时间。但这些类的API可读性差、使用繁琐,且非线程安全,如同设计的翔一样的IO,也是Java让人诟病的一大原因。

于是Java8推出全新日期时间类。这些类的API功能强大简便、线程安全。

但毕竟Java8刚出这些类,诸如序列化、数据访问等类库都不支持Java8日期时间类,需在新老类中来回切换。比如,在业务逻辑层使用LocalDateTime,存入数据库或者返回前端的时候还要切换回Date。因此,还不如沿用老的日期时间类。

不过我们生活在最好的时代,基本主流类库都支持新日期时间类型,但还有项目因还是用祖传日期时间类,出现很多古今交错的错误实践。

比如

  • 通过随意修改时区,使读取到的数据匹配当前时钟
  • 直接对读取到的数据做加、减几个小时的操作,来“修正数据”

本文旨在分析古今时间错乱的本质原因,看看使用遗留日期时间类,来处理日期时间初始化、格式化、解析、计算等可能会遇到的问题,以及如何使用新日期时间类解决。

2 初始化日期时间

  • 初始化2020年11月11日11点11分11秒时间,这样可行吗?
  • 大厂日期时间处理最佳实践(上)1 背景2 初始化日期时间
  • 日志输出时间是3029年12月11日11点11分11秒:
date : Sat Dec 11 11:11:11 CST 3920      

这明显是彩笔才会写的垃圾代码,因为

  • 年应该是和1900差值
  • 月应该是 0~11 而非 1~12
  • 时应该是 0~23,而非 1~24
  • 大厂日期时间处理最佳实践(上)1 背景2 初始化日期时间
  • 修正上述代码如下:
Date date = new Date(2020 - 1900, 10, 11, 11, 11, 11);      
  • 日志输出:
Mon Nov 11 11:11:11 CST 2019      

当有国际化需求时,又得使用Calendar类初始化时间。

使用Calendar改造后,初始化时年参数直接使用当前年即可,月0~11。亦可直接使用Calendar.DECEMBER初始化月份,肯定不会犯错。

  • 分别使用当前时区和纽约时区初始化两个相同日期:
  • 大厂日期时间处理最佳实践(上)1 背景2 初始化日期时间
  • 日志输出
  • 大厂日期时间处理最佳实践(上)1 背景2 初始化日期时间
  • 显示两个不同时间,说明时区发生作用。但更习惯年/月/日 时:分:秒日期时间格式,对现在输出的日期格式还不满意,那就格式化日期时间