一、介绍
Java 8引入了新的时间日期API,其中DateTimeFormatter是对日期时间格式化的实用类。它提供了一种简便的方法来格式化日期和时间,同时还可以将日期和时间字符串解析为Java对象。
二、特性
DateTimeFormatter具有以下特性:
1. 线程安全:在多线程应用程序中使用DateTimeFormatter时,无需考虑同步问题。
2. 不可变性:DateTimeFormatter对象创建后不可修改,确保了线程安全性。
3. 支持各种日期时间格式:DateTimeFormatter支持多种日期时间格式,同时还支持自定义格式。
4. 扩展性:可以用DateTimeFormatterBuilder类创建自定义格式。
三、原理
DateTimeFormatter类使用基于模式的方法来格式化日期和时间字符串。它使用预定义的格式指令来识别和象征化日期和时间字段。这些指令可以组合在一起,形成各种期望的格式化日期和时间字符串。
四、使用场景
1. 日期和时间字符串转换为Java对象:使用DateTimeFormatter将字符串解析为日期时间对象。
2. 格式化日期和时间:使用DateTimeFormatter按指定格式将日期和时间格式化为字符串。
3. 多语言支持:根据不同的语言环境,使用不同的DateTimeFormatter格式化日期时间。
五、注意事项
1. 与SimpleDateFormat相比,DateTimeFormatter是线程安全的,可以放心地在多线程环境中使用。
2. 合理使用DateTimeFormatterBuilder类创建自定义格式,以确保应用程序满足用户的要求,并提高用户体验。
六、补充内容
除了基本的日期、时间、时区等格式化选项,DateTimeFormatter还提供了一些额外的功能,如本地化,ISO格式日期时间格式,精度控制等。
七、实际应用
1. 案例一
(1) 场景
以下是在Java中使用DateTimeFormatter进行日期时间格式化
(2) 代码
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
/**
* DateTimeFormatter使用案例
*
* @author wxy
* @since 2023-05-29
*/
public class DateTimeFormatterCase1 {
private static final DateTimeFormatter SECOND_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
private static final DateTimeFormatter DAY_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
public static void main(String[] args) {
// 获取现在日期时间
LocalDateTime nowDateTime = LocalDateTime.now();
System.out.println("格式化前(LocalDateTime): " + nowDateTime);
System.out.println("格式化后(String): " + nowDateTime.format(SECOND_FORMATTER));
// 解析字符串为日期
String dateStr = "1990-01-01";
LocalDate dateTime = LocalDate.parse(dateStr, DAY_FORMATTER);
System.out.println("转换前(String): " + dateStr);
System.out.println("转换后(LocalDate): " + dateTime);
}
}
2. 案例二
(1) 场景
验证DateTimeFormatter是否线程安全,对比多线程下SimpleDateFormat和DateTimeFormatter区别。
(2) 代码
import java.text.SimpleDateFormat;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.concurrent.TimeUnit;
/**
* DataTimeFormatterCase2: 对比多线程下SimpleDateFormat和DateTimeFormatter区别
*
* @author wxy
* @since 2023-05-29
*/
public class DataTimeFormatterCase2 {
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 2; i++) {
new Thread(() -> {
for (int j = 0; j < 3; j++) {
try {
// 休眠100ms
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
/// 使用DateTimeFormatter将字符串转换为日期格式
//LocalDate dateTime = LocalDate.parse("2022-01-01 10:00:00", DATE_TIME_FORMATTER);
/// 使用SimpleDateFormat将字符串转换为日期格式(多线程报错: java.lang.NumberFormatException: multiple points)
Date dateTime = DATE_FORMAT.parse("2022-01-01 10:00:00");
System.out.println("转换后: " + dateTime);
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
// 休眠1000ms
TimeUnit.MILLISECONDS.sleep(1000);
}
}
输出结果1:多线程下,使用SimpleDateFormat报错(线程不安全):
主要是因为SimpleDateFormat在多线程环境下,是线程不安全的,所以如果你在多线程环境中共享了SimpleDateFormat的实例。
输出结果2:多线程下使用DateTimeFormatter,无报错(线程安全):