在 Java 中,将 String 转换为 Date 对象是常见的操作。由于 java.util.Date 已逐渐被新的日期时间 API(java.time 包)取代,推荐使用 Java 8 引入的 LocalDateTimeZonedDateTimeInstant 等类。但为了兼容性和全面性,下面分别介绍 传统方式(Date + SimpleDateFormat)现代方式(java.time)


✅ 推荐方式:使用 java.time(Java 8+)

1. StringLocalDateTime

适用于没有时区信息的日期时间字符串。

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. StringLocalDate

仅日期(无时间)。

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. StringLocalTime

仅时间。

import java.time.LocalTime;

String timeStr = "12:30:45";
LocalTime time = LocalTime.parse(timeStr);
System.out.println(time); // 12:30:45

4. StringZonedDateTime(带时区)

适用于包含时区信息的字符串。

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. StringInstant(时间戳)

适用于 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

⚠️ 传统方式:Stringjava.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

❗ 常见错误与注意事项

  1. DateTimeParseException / ParseException

    • 原因:字符串格式与模式不匹配。
    • 解决:检查格式模式是否一致,如 HH vs hh(12小时制)。
  2. 时区问题

    • 使用 ZonedDateTimeOffsetDateTime 处理带时区的时间。
  3. 线程安全

    • SimpleDateFormat 非线程安全,DateTimeFormatter 是线程安全的。
  4. 默认格式

    • 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 中将字符串转日期的首选方式,简洁、安全、高效。