DateTimeFormatter ✨

在使用旧的Date对象时,我们使用SimpleDateFromat进行格式化显示。使用新的LocalDateTimeZonedDateTime时,我们要进行格式化显示,就要用DateTimeFormatter

SimpleDateFormat不同的是,DateTimeFormatter不但是不变对象,它还是线程安全的。SimpleDateFormat不是线程安全的,使用的时候,只能在方法内部创建新的局部变量。而DateTimeFormatter可以只创建一个实例,到处引用。

创建DateTimeFormatter时,通过传入格式化字符串来实现:

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

另一种创建方法是,传入格式化字符串时,同时执行Locale

LocalDateTime date = LocalDateTime.now();
DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("E, yyyy-MMMM-dd HH:mm", Locale.US);
System.out.println(formatter1.format(date));  // Mon, 2025-January-20 14:02

DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("E, yyyy-MMMM-dd HH:mm", Locale.CHINESE);
System.out.println(formatter2.format(date));  // 周一, 2025-一月-20 14:02

这种方式可以按照Locale默认习惯格式化:

ZonedDateTime zonedDateTime = ZonedDateTime.now();
var formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm ZZZZ");
System.out.println(formatter.format(zonedDateTime));    // 2023-08-26T21:50 GMT+08:00

var zhFormatter = DateTimeFormatter.ofPattern("yyyy MMM dd EE HH:mm", Locale.CHINA);
System.out.println(zhFormatter.format(zonedDateTime));  // 2023 8月 26 周六 21:50

var usFormatter = DateTimeFormatter.ofPattern("E, MMMM/dd/yyyy HH:mm", Locale.US);
System.out.println(usFormatter.format(zonedDateTime));   // Sat, August/26/2023 21:50

如果要自定义输出的格式,或者要把一个非ISO 8601格式的字符串解析成LocalDateTime,可以使用新的DateTimeFormatter

LocalDateTime提供了对日期和时间进行加减的非常简单的链式调用:

注意到月份加减会自动调整日期,例如从2020-12-31减去1个月得到的结果是2020-11-30,因为11月没有31日。

对日期和时间进行调整则使用withXxx()方法,例如:withHour(15)会把10:11:12变为15:11:12

  • 调整年:withYear()

  • 调整月:withMonth()

  • 调整日:withDayOfMonth()

  • 调整时:withHour()

  • 调整分:withMinute()

  • 调整秒:withSecond()

同样注意到调整月份时,会相应地调整日期,即把2020-12-31的月份调整为9时,日期也自动变为30

实际上,LocalDateTime还有一个通用的with()方法允许我们做更复杂的运算。例如:

对于计算某个月第1个周日这样的问题,新的API可以轻松完成。

要判断两个LocalDateTime的先后,可以使用isBefore()isAfter()方法,对于LocalDateLocalTime类似:

注意到LocalDateTime无法与时间戳进行转换,因为LocalDateTime没有时区,无法确定某一时刻。后面我们要介绍的ZonedDateTime相当于LocalDateTime加时区的组合,它具有时区,可以与long表示的时间戳进行转换。

最后更新于

这有帮助吗?