杰瑞科技汇

Java字符串如何转换为日期?

核心要点

  1. 旧版 API (java.util.DateSimpleDateFormat)

    • java.util.Date:一个“遗留”类,设计上有很多问题,例如它同时包含日期和时间,且月份从 0 开始。
    • SimpleDateFormat:用于解析和格式化日期,它是非线程安全的,在多线程环境下使用会引发严重问题。
    • 不推荐在新项目中使用,但维护旧代码时必须了解。
  2. 新版 API (java.time 包)

    • Java 8 引入了一套全新的、不可变且线程安全的日期时间 API,位于 java.time 包下。
    • 这是目前官方推荐的最佳实践
    • 主要类包括:
      • LocalDate:只表示日期(年、月、日)。
      • LocalTime:只表示时间(时、分、秒、纳秒)。
      • LocalDateTime:表示日期和时间,但不包含时区信息。
      • ZonedDateTime:表示带有时区的日期和时间。
      • DateTimeFormatter:用于解析和格式化日期,它是线程安全的。

使用新版 API (Java 8+) - 推荐

这是最现代、最安全、最推荐的方式。

步骤:

  1. 定义你的日期字符串格式。
  2. 创建 DateTimeFormatter 实例,并应用该格式。
  3. 使用 LocalDate.parse()LocalDateTime.parse() 等静态方法,传入字符串和 DateTimeFormatter 进行解析。

示例代码:

解析为 LocalDate (仅日期)

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
public class StringToDateExample {
    public static void main(String[] args) {
        String dateString = "2025-10-27";
        // 定义格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        try {
            // 将字符串解析为 LocalDate
            LocalDate localDate = LocalDate.parse(dateString, formatter);
            System.out.println("原始字符串: " + dateString);
            System.out.println("解析后的 LocalDate: " + localDate);
            System.out.println("年份: " + localDate.getYear());
            System.out.println("月份: " + localDate.getMonthValue());
            System.out.println("日期: " + localDate.getDayOfMonth());
        } catch (DateTimeParseException e) {
            System.err.println("日期格式解析失败,请检查字符串格式是否正确: " + e.getMessage());
        }
    }
}

输出:

原始字符串: 2025-10-27
解析后的 LocalDate: 2025-10-27
年份: 2025
月份: 10
日期: 27

解析为 LocalDateTime (日期和时间)

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class StringToDateTimeExample {
    public static void main(String[] args) {
        String dateTimeString = "2025-10-27 15:30:45";
        // 定义格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        try {
            // 将字符串解析为 LocalDateTime
            LocalDateTime localDateTime = LocalDateTime.parse(dateTimeString, formatter);
            System.out.println("原始字符串: " + dateTimeString);
            System.out.println("解析后的 LocalDateTime: " + localDateTime);
            System.out.println("小时: " + localDateTime.getHour());
            System.out.println("分钟: " + localDateTime.getMinute());
        } catch (Exception e) {
            System.err.println("日期时间格式解析失败: " + e.getMessage());
        }
    }
}

输出:

原始字符串: 2025-10-27 15:30:45
解析后的 LocalDateTime: 2025-10-27T15:30:45
小时: 15
分钟: 30

处理不同格式

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class DifferentFormatExample {
    public static void main(String[] args) {
        // 格式1: "2025/10/27"
        String dateStr1 = "2025/10/27";
        DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("yyyy/MM/dd");
        LocalDate date1 = LocalDate.parse(dateStr1, formatter1);
        System.out.println("格式1解析结果: " + date1);
        // 格式2: "27-Oct-2025" (使用英文月份缩写)
        String dateStr2 = "27-Oct-2025";
        // 可以指定 Locale 来确保月份名称解析正确
        DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("dd-MMM-yyyy", Locale.ENGLISH);
        LocalDate date2 = LocalDate.parse(dateStr2, formatter2);
        System.out.println("格式2解析结果: " + date2);
        // 格式3: "20251027" (紧凑格式)
        String dateStr3 = "20251027";
        DateTimeFormatter formatter3 = DateTimeFormatter.ofPattern("yyyyMMdd");
        LocalDate date3 = LocalDate.parse(dateStr3, formatter3);
        System.out.println("格式3解析结果: " + date3);
    }
}

使用旧版 API (java.util.DateSimpleDateFormat) - 不推荐

如果你正在维护旧的 Java 代码(Java 7 或更早),你可能会遇到这种方式。

步骤:

  1. 定义你的日期字符串格式。
  2. 创建 SimpleDateFormat 实例,并应用该格式。
  3. 调用 parse() 方法进行解析。

示例代码:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class LegacyStringToDateExample {
    public static void main(String[] args) {
        String dateString = "2025-10-27";
        // 定义格式
        // 注意:SimpleDateFormat 不是线程安全的!
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        try {
            // 将字符串解析为 Date
            Date date = formatter.parse(dateString);
            System.out.println("原始字符串: " + dateString);
            // Date.toString() 输出的格式不是我们想要的,它包含时区信息
            System.out.println("解析后的 java.util.Date: " + date); 
            System.out.println("Date.getTime() (时间戳): " + date.getTime());
        } catch (ParseException e) {
            System.err.println("日期格式解析失败: " + e.getMessage());
        }
    }
}

重要警告: SimpleDateFormat非线程安全的,如果在多线程环境中共享同一个 SimpleDateFormat 实例,可能会导致数据损坏或解析异常,如果必须在旧版代码中使用,请为每个线程创建新的实例,或者使用 ThreadLocal 来封装它。


常见格式模式字母

DateTimeFormatterSimpleDateFormat 中,使用特定的字母来表示日期和时间的部分。

字母 含义 示例
y yyyy (2025), yy (23)
M MM (10), M (10), MMM (Oct), MMMM (October)
d dd (27), d (27)
H 小时 (24小时制) HH (15)
h 小时 (12小时制) hh (03)
m 分钟 mm (30)
s ss (45)
a 上午/下午标记 a (PM)
z 时区名称 z (GMT+08:00, CST)

总结与建议

特性 java.time (推荐) java.util.Date (不推荐)
线程安全 (所有类都是不可变的) (SimpleDateFormat 是问题根源)
API 设计 清晰、丰富、类型安全 (如 LocalDate, LocalTime) 混乱,Date 类同时包含日期和时间
时区处理 强大的 ZonedDateTimeZoneId 处理起来很麻烦
可读性 方法名如 getYear(), plusDays() 更直观 方法名如 getYear() 已废弃,使用 getTime() 获取时间戳
版本要求 Java 8+ Java 1.1+

最终建议:

  • 新项目:请务必使用 java.time 包,这是未来的方向,也是业界公认的最佳实践。
  • 维护旧项目:如果代码库已经大量使用了 java.util.DateSimpleDateFormat,在修改时需要特别注意线程安全问题,如果有机会,可以考虑逐步将代码迁移到 java.time
分享:
扫描分享到社交APP
上一篇
下一篇