DateTimeFormatter ✨
在使用旧的Date对象时,我们使用SimpleDateFromat进行格式化显示。使用新的LocalDateTime或ZonedDateTime时,我们要进行格式化显示,就要用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()方法,对于LocalDate和LocalTime类似:
注意到LocalDateTime无法与时间戳进行转换,因为LocalDateTime没有时区,无法确定某一时刻。后面我们要介绍的ZonedDateTime相当于LocalDateTime加时区的组合,它具有时区,可以与long表示的时间戳进行转换。
最后更新于
这有帮助吗?