1. 概述
本文将系统性地介绍在 Java 中如何将 String
转换为 Date
对象的多种方法。我们首先从 Java 8 引入的现代日期时间 API —— java.time
包开始,然后回顾传统 java.util.Date
的处理方式。
最后,我们还会探讨一些常用的第三方库,如 Joda-Time 和 Apache Commons Lang 的 DateUtils
,它们在某些场景下能显著简化日期处理的复杂度。
✅ 掌握这些技巧,能帮你避免大量“时区踩坑”和格式解析异常。
2. 将字符串转换为 LocalDate 或 LocalDateTime
LocalDate
和 LocalDateTime
是不可变的时间对象,分别表示“日期”和“日期+时间”。它们属于 java.time
包,是 Java 8 之后推荐使用的日期类型。
默认情况下,Java 使用 ISO-8601 标准格式,因此如果字符串符合该标准,可直接使用 parse()
方法解析。
⚠️ 注意:LocalDate
和 LocalDateTime
不包含时区信息。若需处理带时区的时间,请使用 ZonedDateTime
。
2.1 使用 parse() API
java.time
提供了 parse()
方法,用于将符合 ISO 格式的字符串直接转换为日期对象。
前提是字符串必须符合 ISO_LOCAL_DATE 或 ISO_LOCAL_DATE_TIME 格式,否则会抛出 DateTimeParseException
。
示例:将字符串转为 LocalDate
LocalDate date = LocalDate.parse("2018-05-05");
示例:将字符串转为 LocalDateTime
LocalDateTime dateTime = LocalDateTime.parse("2018-05-05T11:50:55");
示例:使用自定义格式解析带时区的时间
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss z");
ZonedDateTime zonedDateTime = ZonedDateTime.parse("2015-05-05 10:15:30 Europe/Paris", formatter);
2.2 使用自定义 DateTimeFormatter
对于非 ISO 格式的字符串,必须使用 DateTimeFormatter
显式定义解析格式。
DateTimeFormatter
提供了丰富的预定义格式,也支持自定义模式。
示例:使用预定义格式 BASIC_ISO_DATE
解析 19590709
String dateInString = "19590709";
LocalDate date = LocalDate.parse(dateInString, DateTimeFormatter.BASIC_ISO_DATE);
示例:解析英文格式的日期字符串,如 "Mon, 05 May 1980"
String dateInString = "Mon, 05 May 1980";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE, d MMM yyyy", Locale.ENGLISH);
LocalDate dateTime = LocalDate.parse(dateInString, formatter);
2.3 常见日期时间格式符号
以下是一些常用的格式化符号,便于快速构建 DateTimeFormatter
:
y
– 年份(1996 或 96)M
– 月份(July、Jul 或 07)d
– 月份中的天(1-31)E
– 星期几(Friday、Sun)a
– 上午/下午标记(AM、PM)H
– 24 小时制小时(0-23)h
– 12 小时制小时(1-12)m
– 分钟(0-59)s
– 秒(0-60,支持闰秒)
📌 完整符号列表参考官方文档:DateTimeFormatter Patterns
💡 提示:如果需要将
java.time
类型转为java.util.Date
,可参考类型转换文章,此处不再赘述。
3. 将字符串转换为 java.util.Date
在 Java 8 之前,日期处理依赖于 java.util.Date
、Calendar
和 TimeZone
这些老 API。虽然现在不推荐使用,但在维护旧系统时仍需掌握。
示例:使用 SimpleDateFormat 解析
SimpleDateFormat formatter = new SimpleDateFormat("dd-MMM-yyyy", Locale.ENGLISH);
String dateInString = "7-Jun-2013";
Date date = formatter.parse(dateInString);
⚠️ 注意:
- 必须先创建
SimpleDateFormat
实例,并指定格式模式。 - 若字符串格式与模式不匹配,会抛出
ParseException
。 SimpleDateFormat
不是线程安全的,多线程环境下应使用DateTimeFormatter
或加锁。
3.1 为 java.util.Date 添加时区信息
java.util.Date
本身不保存时区,它只是自 Unix 纪元(1970-01-01T00:00:00Z)以来的毫秒数。
但打印时会使用 JVM 默认时区进行格式化。
示例:指定时区格式化解析
SimpleDateFormat formatter = new SimpleDateFormat("dd-M-yyyy hh:mm:ss a", Locale.ENGLISH);
formatter.setTimeZone(TimeZone.getTimeZone("America/New_York"));
String dateInString = "22-01-2015 10:15:55 AM";
Date date = formatter.parse(dateInString);
String formattedDateString = formatter.format(date);
❌ 不推荐做法:修改 JVM 全局时区
TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
这种操作会影响整个应用,极易引发“时区错乱”问题,属于高危操作,应避免。
4. 第三方库支持
除了 JDK 自带 API,一些成熟库也能简化日期解析。
4.1 Joda-Time 库
Joda-Time 曾是 Java 日期处理的事实标准。虽然其作者已建议迁移到 java.time
(JSR-310),但在老项目中仍广泛使用。
Maven 依赖:
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.12.5</version>
</dependency>
示例:解析标准日期时间
DateTimeFormatter formatter = DateTimeFormat.forPattern("dd/MM/yyyy HH:mm:ss");
String dateInString = "07/06/2013 10:11:59";
DateTime dateTime = DateTime.parse(dateInString, formatter);
示例:设置特定时区
DateTimeFormatter formatter = DateTimeFormat.forPattern("dd/MM/yyyy HH:mm:ss");
String dateInString = "07/06/2013 10:11:59";
DateTime dateTime = DateTime.parse(dateInString, formatter);
DateTime dateTimeWithZone = dateTime.withZone(DateTimeZone.forID("Asia/Kolkata"));
✅ 优点:API 设计优雅,时区处理清晰。
⚠️ 建议:新项目直接用 java.time
,老项目可继续使用。
4.2 Apache Commons Lang – DateUtils
DateUtils
是 Apache Commons Lang3 提供的工具类,极大简化了 Date
和 Calendar
的操作。
Maven 依赖:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.14.0</version>
</dependency>
示例:支持多格式自动匹配解析
String dateInString = "07/06-2013";
Date date = DateUtils.parseDate(dateInString,
new String[] { "yyyy-MM-dd HH:mm:ss", "dd/MM-yyyy" });
✅ 亮点:
- 支持传入多个可能的格式,自动尝试匹配。
- 避免了手动 try-catch 多个
SimpleDateFormat
的繁琐逻辑。 - 在处理用户输入或不规范数据时非常实用。
5. 总结
本文覆盖了 Java 中字符串转日期的主要方式:
方式 | 适用场景 | 推荐度 |
---|---|---|
LocalDate.parse() |
ISO 格式字符串 | ✅✅✅ |
DateTimeFormatter |
自定义格式 | ✅✅✅ |
SimpleDateFormat |
老系统维护 | ⚠️(注意线程安全) |
Joda-Time | 遗留项目 | ✅(但建议迁移) |
DateUtils.parseDate() |
多格式兼容解析 | ✅✅ |
📌 最佳实践建议:
- 新项目统一使用
java.time
API - 避免
SimpleDateFormat
在多线程环境直接共享 - 处理用户输入时优先考虑
DateUtils
的多格式支持
完整示例代码已托管至 GitHub:
https://github.com/baeldung/tutorials/tree/master/core-java-modules/core-java-datetime-string