Java 8 DateTimeFormatter 踩坑

1. 问题描述

本月是 2019 年的第一个月,除了迎接新年之外同样也迎来了跨年带来的关于时间参数的 bug。

废话不多说,进入正题。之前写了一个任务调度系统,支持以周为粒度进行任务的调度。针对任务的每次运行都会产生一个批次号,一般以 任务名_<年份><周数> 的格式编号(比如 job_201850 ),但是在 2018 年 12 月 31 日却发现了自然周的序号发生了跳跃。

2. 分析出问题的代码

查看了一下代码,问题出在 DateTime 格式化上,原来的 DateTimeFormatter 的定义如下:

  DateTimeFormatter.ofPattern("yyyyww")

预想的是 yyyy 代表年,ww 代表自然周,对于 2018 年 12 月 31 日原本预计得到的结果是 201853,但是此处 ww 得到的结果竟然是 01。

百思不得其解之下上网查了一下,发现原来错的不是 ww,而是 yyyy

一般来说 yyyy 是和自然年的月份、日期搭配的,对于和自然周的搭配是要用 YYYY 的。代码如下:

  @Test
  public void testForWeek() {
      DateTimeFormatter rightFormatter = DateTimeFormatter.ofPattern("YYYYww");
      DateTimeFormatter wrongFormatter = DateTimeFormatter.ofPattern("yyyyww");
  
      LocalDateTime now = LocalDateTime.of(2019, 1, 7, 0, 30, 0);
      System.out.println(now);
      String right = rightFormatter.format(now);
      String wrong = wrongFormatter.format(now);
      System.out.println("right = " + right);
      System.out.println("wrong = " + wrong);
  
      now = LocalDateTime.of(2018, 12, 31, 0, 30, 0);
      System.out.println(now);
      right = rightFormatter.format(now);
      wrong = wrongFormatter.format(now);
      System.out.println("right = " + right);
      System.out.println("wrong = " + wrong);
  }

输出结果:

  2019-01-07T00:30
  right = 201902
  wrong = 201902
  2018-12-31T00:30
  right = 201901
  wrong = 201801

也就是说 2018 年 12 月 31 日实际上算是 2019 年的第一周,这也算刷新了我的认知!

发表评论

电子邮件地址不会被公开。 必填项已用*标注