Java 时间处理tips

189 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

Java对时间的处理在我职业生涯很早的时候就开始了,只是当时还没领教其中的复杂和坑。最近的项目默认都会涉及海外用户,对时区的处理尤其重要,特别是冬夏令时的存在让整个处理更复杂了些。在Java的远古时期,下面是处理时间的三件套:

  • Date
  • Calendar
  • SimpleDateFormat 时至今日还是有很多人在使用,谁能拒绝Date date = new Date()这样简单明了的东西呢?也无可厚非,很多公司一时半会业务范围根本扩张不到海外,而且只存创建、更新时间之类的比较基础的字段,自然是不需要更新迭代的。但一旦涉及到了时区的转换,那Date对象处理起来就很吃力了。因为Date本身并没有保存任何时区的信息,即使在源码中找到一些看起来比较像时区的方法去设置,大多数也是不能成功的。

另外一点,时间的比较和加减也没有一个好用的API提供实现,在Java 8之前一般是需要自己去写一些工具类的。这个时候就会用到Calendar对象,分别对年月日时分秒做处理:

image.png

另外一个问题就是格式化输出,这个相对比较简单:

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

这里的patten可以定义成很多形式。

自动Java 8发布以来,新增了LocalDateTime和ZonedDateTime分别对应常规日期的处理和带时区的日期处理。来感受一下其方便的API:

LocalDateTime now = LocalDateTime.now();//获取当前时间
//3小时后
LocalDateTime localDateTime1 = now.plusHours(3);
//3分钟前
LocalDateTime localDateTime2 = now.minusMinutes(3);
//明年今日
LocalDateTime localDateTime3 = now.plusYears(1);
//去年今日
LocalDateTime localDateTime4 = now.minusYears(1);
//时间比较
localDateTime1.isAfter(localDateTime2);

可以说是傻瓜式处理,再也不用写复杂的转换,抛开这个干扰项,可以更专注于业务的实现。

再看看对于时区的处理,这里需要介绍一个时区对象:ZoneId

//获取中国时区的当前时间
ZonedDateTime time = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
//把localDateTime转成带时区的
ZonedDateTime la = localDateTime.atZone(ZoneId.of("America/Los_Angeles"));
//两个时区之间的转换
ZonedDateTime la = time.atZone(ZoneId.of("Asia/Shanghai")).withZoneSameInstant(ZoneId.of("America/Los_Angeles"));

就是这么简单。