在 Java 中,将 String 转换为 Date 对象是常见的操作。由于 java.util.Date 已逐渐被新的日期时间 API(java.time 包)取代,推荐使用 Java 8 引入的 LocalDateTime、ZonedDateTime 或 Instant 等类。但为了兼容性和全面性,下面分别介绍 传统方式(Date + SimpleDateFormat) 和 现代方式(java.time)。
✅ 推荐方式:使用 java.time(Java 8+)
1. String → LocalDateTime
适用于没有时区信息的日期时间字符串。
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class StringToDate {
public static void main(String[] args) {
String dateTimeStr = "2025-08-04 12:30:45";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime dateTime = LocalDateTime.parse(dateTimeStr, formatter);
System.out.println(dateTime); // 2025-08-04T12:30:45
}
}
2. String → LocalDate
仅日期(无时间)。
import java.time.LocalDate;
String dateStr = "2025-08-04";
LocalDate date = LocalDate.parse(dateStr);
// 默认格式 yyyy-MM-dd,也可指定 formatter
System.out.println(date); // 2025-08-04
3. String → LocalTime
仅时间。
import java.time.LocalTime;
String timeStr = "12:30:45";
LocalTime time = LocalTime.parse(timeStr);
System.out.println(time); // 12:30:45
4. String → ZonedDateTime(带时区)
适用于包含时区信息的字符串。
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
String zonedStr = "2025-08-04T12:30:45+08:00";
ZonedDateTime zdt = ZonedDateTime.parse(zonedStr);
System.out.println(zdt); // 2025-08-04T12:30:45+08:00[Asia/Shanghai]
5. String → Instant(时间戳)
适用于 ISO 标准时间戳字符串。
import java.time.Instant;
String instantStr = "2025-08-04T04:30:45Z";
Instant instant = Instant.parse(instantStr);
System.out.println(instant); // 2025-08-04T04:30:45Z
⚠️ 传统方式:String → java.util.Date(不推荐,但需了解)
import java.text.SimpleDateFormat;
import java.util.Date;
import java.text.ParseException;
public class StringToDateLegacy {
public static void main(String[] args) {
String str = "2025-08-04 12:30:45";
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
Date date = formatter.parse(str);
System.out.println(date); // Mon Aug 04 12:30:45 CST 2025
} catch (ParseException e) {
e.printStackTrace();
}
}
}
❗ 注意:
SimpleDateFormat不是线程安全的,多线程环境下需用ThreadLocal或改用DateTimeFormatter。java.util.Date的很多方法已过时(如getYear()),建议避免使用。
🔧 常见格式模式(Pattern)
| 模式 | 含义 | 示例 |
|---|---|---|
yyyy |
四位年份 | 2025 |
MM |
两位月份 | 08 |
dd |
两位日期 | 04 |
HH |
24小时制小时 | 12 |
mm |
分钟 | 30 |
ss |
秒 | 45 |
SSS |
毫秒 | 123 |
E |
星期 | Mon |
a |
上午/下午 | PM |
❗ 常见错误与注意事项
DateTimeParseException/ParseException- 原因:字符串格式与模式不匹配。
- 解决:检查格式模式是否一致,如
HHvshh(12小时制)。
时区问题
- 使用
ZonedDateTime或OffsetDateTime处理带时区的时间。
- 使用
线程安全
SimpleDateFormat非线程安全,DateTimeFormatter是线程安全的。
默认格式
LocalDate.parse()默认接受yyyy-MM-dd,其他格式需自定义formatter。
✅ 最佳实践
| 推荐做法 | 说明 |
|---|---|
✅ 使用 java.time API |
更清晰、线程安全、功能强大 |
✅ 预定义 DateTimeFormatter 常量 |
提高性能,避免重复创建 |
| ✅ 处理异常 | 使用 try-catch 捕获解析异常 |
| ✅ 使用 ISO 标准格式 | 如 yyyy-MM-dd'T'HH:mm:ss,便于系统间交互 |
// 推荐:定义常量格式器
public class DateUtils {
public static final DateTimeFormatter DT_FORMAT =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
}
📌 总结
| 场景 | 推荐方式 |
|---|---|
| 一般日期时间转换 | LocalDateTime.parse(str, formatter) |
| 仅日期 | LocalDate.parse(str) |
| 仅时间 | LocalTime.parse(str) |
| 带时区时间 | ZonedDateTime.parse(str) |
| 时间戳 | Instant.parse(str) |
| 旧系统兼容 | SimpleDateFormat.parse(str)(注意异常和线程安全) |
✅ 一句话掌握:
使用java.time.LocalDateTime.parse()+DateTimeFormatter是现代 Java 中将字符串转日期的首选方式,简洁、安全、高效。