首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >还在用 SimpleDateFormat, 来试试 DateTimeFormatter

还在用 SimpleDateFormat, 来试试 DateTimeFormatter

原创
作者头像
Dylan Liu
修改2020-11-19 11:36:55
7860
修改2020-11-19 11:36:55
举报
文章被收录于专栏:dylanliudylanliu

说明

1.8 以前 Java 关于日期的类是 DateCalendar, 与之对应的格式化的类是 SimpleDateFormat。 上一篇介绍了在1.8 中提供的 java.time 包, Java 提供了更加丰富的时间类型来供我们使用,与之对应的格式化类型也需要使用新提供的 DateTimeFormatter

优缺点比较

很多文章写过 SimpleDateFormat 类,每当提到它,都会让开发人员注意这个类并不是线程安全的,也就是每次使用都必须新生成,而不能当作全局静态变量来使用。

就像 Date 是可变类型是一个设计失误一样,SimpleDateFormat 设计为非线程安全也是一个设计失误,这样的设计失误却需要由程序员来承担。DateTimeFormatter 纠正了这个设计失误,变为了线程安全的。

DateTimeFormatter 在职责分离上也更清晰,由于 Date 没有时区 的信息,所以在格式化时这个任务就只能由 SimpleDateFormat 承担,导致很难理解 SimpleDateFormat 如何处理时区。 新增加的 ZonedDateTime 等时间类增加了时区及与时区无关的 LocalDateTime 类,DateTimeFormatter 就可以专注于解析与格式化的工作。

使用方法

DateTimeFormatter 提供的方法命名上遵循 java.time 包的一贯原则,提供了很多静态方法来生成一个 DateTimeFormatter

格式化当地时间:

// 作为静态字段,线程安全,各个方法都可以使用
public static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");


public static String format() { 
    LocalDateTime localDateTime = LocalDateTime.now();
    
    return formatter.format(localDateTime);
」

DateTimeFormatter 的 pattern 与 SimpleDateFormat 中的完全一致,因此没有额外学习成本。

上例使用的是当地时间,如果一个跨国公司要处理时间,就必须考虑到不同国家所在的时区不同,使用服务器所配置的时区就不行了,必须显式地将时区加到处理代码中。

假设我们从美国买了一件东西,美国的物流传了一个时间戳我们,需要在网站上显示给国内的用户。此时我们显式地指定时区(LocalDateTime 中不保存时区,我们只是用它来生成本地时间):

public static final ZoneId BEIJING = ZoneId.of("+08:00");
public static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

public static String format(Long timestampMillis) {
    LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(timestampMillis), zoneId);

    return formatter.format(localDateTime);
}

解析时间与格式化时间不太一致,由于时区存在于 ZonedDateTime 类中而不存在于 LocalDateTime,因此解析时间是将 DateTimeFormatter 传入时间类中来实现的,由各个时间类来决定存储的形式。

public static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss z");

public ZonedDateTime parse(String dateTime) {
    ZonedDateTime zonedDateTime = ZonedDateTime.parse(dateTime, formatter);

    return zonedDateTime;
}

//调用 parse("2020-11-17 21:52:31 +08:00")

关注我

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 说明
  • 优缺点比较
  • 使用方法
  • 关注我
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档