一切福田,不離方寸,從心而覓,感無不通。

Java日期处理易踩的十个坑

前言

整理了Java日期处理的十个坑,希望对大家有帮助。

一、用Calendar设置时间的坑

反例:

 

运行结果:

 

解析:

我们设置了10小时,但运行结果是22点,而不是10点。因为Calendar.HOUR默认是按12小时制处理的,需要使用Calendar.HOUR_OF_DAY,因为它才是按24小时处理的。

正例:

 

二、Java日期格式化YYYY的坑

反例:

 

运行结果:

 

解析:

为什么明明是2019年12月31号,就转了一下格式,就变成了2020年12月31号了?因为YYYY是基于周来计算年的,它指向当天所在周属于的年份,一周从周日开始算起,周六结束,只要本周跨年,那么这一周就算下一年的了。正确姿势是使用yyyy格式。

正例:

 

三、Java日期格式化hh的坑。

反例:

 

运行结果:

 

解析:

设置的时间是12点,为什么运行结果是0点呢?因为hh是12制的日期格式,当时间为12点,会处理为0点。正确姿势是使用HH,它才是24小时制。

正例:

 

四、Calendar获取的月份比实际数字少1即(0-11)

反例:

 

运行结果:

 

解析:

 

正例:

 

五、Java日期格式化DD的坑

反例:

 

运行结果:

 

解析:

DD和dd表示的不一样,DD表示的是一年中的第几天,而dd表示的是一月中的第几天,所以应该用的是dd。

正例:

 

六、SimleDateFormat的format初始化问题

反例:

 

运行结果:

 

解析:

用format格式化日期是,要输入的是一个Date类型的日期,而不是一个整型或者字符串。

正例:

 

七、日期本地化问题

反例:

 

运行结果:

 

解析:

DateTimeFormatter 这个类默认进行本地化设置,如果默认是中文,解析英文字符串就会报异常。可以传入一个本地化参数(Locale.US)解决这个问题

正例:

 

八、SimpleDateFormat 解析的时间精度问题

反例:

 

运行结果:

 

解析:

SimpleDateFormat 可以解析长于/等于它定义的时间精度,但是不能解析小于它定义的时间精度。

正例:

 

九、SimpleDateFormat 的线性安全问题

反例:

 

运行结果:

 

解析:

全局变量的SimpleDateFormat,在并发情况下,存在安全性问题。

  • SimpleDateFormat继承了 DateFormat
  • DateFormat类中维护了一个全局的Calendar变量
  • sdf.parse(dateStr)和sdf.format(date),都是由Calendar引用来储存的。
  • 如果SimpleDateFormat是static全局共享的,Calendar引用也会被共享。
  • 又因为Calendar内部并没有线程安全机制,所以全局共享的SimpleDateFormat不是线性安全的。

解决SimpleDateFormat线性不安全问题,有三种方式:

  • 将SimpleDateFormat定义为局部变量
  • 使用ThreadLocal。
  • 方法加同步锁synchronized。

正例:

 

十、Java日期的夏令时问题

反例:

 

运行结果:

 

解析:

先了解一下夏令时

  • 夏令时,表示为了节约能源,人为规定时间的意思。
  • 一般在天亮早的夏季人为将时间调快一小时,可以使人早起早睡,减少照明量,以充分利用光照资源,从而节约照明用电。
  • 各个采纳夏时制的国家具体规定不同。目前全世界有近110个国家每年要实行夏令时。
  • 1986年4月,中国中央有关部门发出“在全国范围内实行夏时制的通知”,具体作法是:每年从四月中旬第一个星期日的凌晨2时整(北京时间),将时钟拨快一小时。(1992年起,夏令时暂停实行。)
  • 夏时令这几个时间可以注意一下哈,1986-05-04, 1987-04-12, 1988-04-10, 1989-04-16, 1990-04-15, 1991-04-14.

结合demo代码,中国在1986-05-04当天还在使用夏令时,时间被拨快了1个小时。所以0点30分打印成了1点30分。如果要打印正确的时间,可以考虑修改时区为东8区。

正例:

 

from:https://www.cnblogs.com/jay-huaxiao/p/12591272.html