推荐课程
DateTimeFormatter
和 SimpleDateFormat
都是用于格式化日期和时间的类,但是它们有一些区别。
SimpleDateFormat
是 Java 早期版本中提供的日期格式化类,他是线程不安全的。由于 SimpleDateFormat
是线程不安全的,所以如果在多线程环境中使用会出现异常,通常的解决方法要么是每个线程独立维护一份 SimpleDateFormat
对象实例,要么是将 SimpleDateFormat
放到 ThreadLocal
中。
在Java 8中新增了 DateTimeFormatter
类,它比 SimpleDateFormat
更加灵活和安全。 DateTimeFormatter
是不变对象,且是线程安全的。所以在使用 DateTimeFormatter
的时候,可以以静态成员变量的方式,在一个类中只维护一份对象实例,用于格式化多个日期和时间值,而无需担心线程安全问题。
DateTimeFormatter
和 SimpleDateFormat
都是 Java 中用于日期和时间格式化的类,但它们之间存在以下区别:
例如,要将日期格式化为法国本地化格式,可以使用以下代码:
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).withLocale(Locale.FRANCE);
LocalDate date = LocalDate.now();
String formattedDate = date.format(formatter);
System.out.println(formattedDate);
总的来说,虽然 SimpleDateFormat
用于简单的日期和时间格式化是很方便的,但是 DateTimeFormatter
在灵活性、线程安全、类型支持、解析能力和本地化方面都更加强大和安全。在 Java 8 及以上的版本中,建议使用 DateTimeFormatter
。
SimpleDateFormat
支持一些常用的格式化选项,例如:
格式化选项描述
年份,例如 2023
月份,例如 05
日期,例如 04
小时(24小时制),例如 13
分钟,例如 30
秒钟,例如 45
毫秒,例如 789
星期几,例如 Tue
时区,例如 +0800
3.1 字符串转日期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String timeStr = "2023-05-04 21:54:27";
Date date = sdf.parse(timeStr);
System.out.println(date);
输出结果为:
2023-05-04 22:15:21
如上所示, SimpleDateFormat
字符串转日期的方法主要是 parse
这个方法,可以将符合定义的字符串转成 Date
类型。
3.2 日期转字符串
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date now = new Date();
String formattedDate = sdf.format(now);
System.out.println(formattedDate);
输出结果为:
Thu May 04 21:54:27 CST 2023
如上所示,日期转字符串的方法是 format
可以将日期 Date
类型的对象转化成字符串的日期格式来展示。
DateTimeFormatter
除了和 SimpleDateFormat
一样支持一些常用的格式化选项以外,还支持一些额外的格式化选项,例如:
格式化选项描述
年份,与
类似,但是对于 BC 纪元来说是负数
纪元,例如 AD 或 BC
季度,例如 Q1
月份,例如 1 或者
DateTimeFormatter
可以用于格式化不同的日期和时间类型,例如 LocalDate
、 LocalTime
、 LocalDateTime
、 ZonedDateTime
、 OffsetDateTime
等。
4.1 字符串转日期
例如,要将字符串 “2023-05-04 13:30:45” 解析为 LocalDateTime
类型,可以使用以下代码:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String dateString = "2023-05-04 13:30:45";
LocalDateTime dateTime = LocalDateTime.parse(dateString, formatter);
System.out.println(dateTime);
输出的结果的格式为:
2023-05-04T13:30:45
如上所示,使用 parse
方法将字符串转化成 LocalDateTime
类型,这里是直接使用 LocalDateTime
的静态方法 parse
,然后将日期的字符串和format的格式当作入参传入。
4.2 日期转字符串
例如,要将 LocalDate 格式化为 “yyyy-MM-dd” 格式的字符串,可以使用以下代码:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate date = LocalDate.now();
String formattedDate = date.format(formatter);
System.out.println(formattedDate);
输出结果为:
2023-05-04
注意:
和 SimpleDateFormat
的使用不同,使用 SimpleDateFormat
的时候是直接用的 SimpleDateFormat
的对象 sdf
来 parse
或者 format
。
而使用 DateTimeFormatter
并不是直接用 DateTimeFormatter
的对象来进行 parse
或者 format
。则是通过 LocalDateTime.parse(dateString, formatter)
来转成日期,通过 LocalDate
的对象 date.format(formatter)
来转成字符串。
类似于 LocalDate
的日期类,可以通过下面的方式创建一个日期:
LocalDate newDate = LocalDate.of(2022, 1, 1);
LocalDate now = LocalDate.now();
当需要在当前日期上加减的时候,可以采用下面的方法:
Period oneMonth = Period.ofMonths(1);
newDate = newDate.plus(oneMonth);
这样newDate的日期会加上一个月。
LocalDate
类中还有很多实用的静态或者普通方法,可以根据实际使用场景选择使用。