核心概念:SimpleDateFormat
在 Java 8 之前,java.text.SimpleDateFormat 是处理日期字符串转换的主要工具。

(图片来源网络,侵删)
- 特点:
- 它不是线程安全的,如果在多线程环境下共享同一个
SimpleDateFormat实例,可能会导致数据错乱或程序异常,最佳实践是在每次使用时都创建一个新的实例。 - 功能强大,但 API 设计有些陈旧。
- 它解析后得到的是
java.util.Date对象,这个对象本身不包含时区信息,但其内部使用 UTC 时间戳表示。
- 它不是线程安全的,如果在多线程环境下共享同一个
SimpleDateFormat 常用格式字符
| 字符 | 含义 | 示例 |
|---|---|---|
y |
年 | yyyy (2025), yy (23) |
M |
月 | MM (09), M (9) |
d |
日 | dd (05), d (5) |
H |
小时 (24小时制) | HH (13), H (13) |
h |
小时 (12小时制) | hh (01), h (1) |
m |
分钟 | mm (09), m (9) |
s |
秒 | ss (05), s (5) |
S |
毫秒 | SSS (123) |
E |
星期几 | EEE (Tue), EEEE (Tuesday) |
z |
时区名称 | z (GMT+08:00), z (China Standard Time) |
使用 SimpleDateFormat (Java 8 及之前版本)
这是传统的方法,适用于需要兼容旧代码或在 Java 8 以下环境中运行的情况。
示例 1:基本转换
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class SimpleDateFormatExample {
public static void main(String[] args) {
// 1. 定义日期字符串和对应的格式模板
String dateString = "2025-10-27 10:30:00";
String pattern = "yyyy-MM-dd HH:mm:ss";
// 2. 创建 SimpleDateFormat 对象 (注意:每次使用都 new 一个新实例)
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
try {
// 3. 调用 parse 方法进行转换
Date date = sdf.parse(dateString);
// 4. 输出结果
System.out.println("原始字符串: " + dateString);
System.out.println("转换后的 Date 对象: " + date);
System.out.println("Date 对象的内部时间戳 (毫秒): " + date.getTime());
// 5. 也可以将 Date 对象格式化回字符串
String formattedDate = sdf.format(date);
System.out.println("格式化后的字符串: " + formattedDate);
} catch (ParseException e) {
System.err.println("日期字符串格式不匹配!请检查字符串和格式模板。");
e.printStackTrace();
}
}
}
输出:
原始字符串: 2025-10-27 10:30:00
转换后的 Date 对象: Fri Oct 27 10:30:00 CST 2025
Date 对象的内部时间戳 (毫秒): 1698340200000
格式化后的字符串: 2025-10-27 10:30:00
示例 2:处理带时区的字符串
如果字符串中包含时区信息,格式模板中也必须包含 z。
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class SimpleDateFormatWithTimeZone {
public static void main(String[] args) {
String dateStringWithZone = "2025-10-27T10:30:00+08:00";
String patternWithZone = "yyyy-MM-dd'T'HH:mm:ssXXX"; // XXX 用于解析ISO-8601格式的时区
SimpleDateFormat sdf = new SimpleDateFormat(patternWithZone);
try {
Date date = sdf.parse(dateStringWithZone);
System.out.println("带时区的字符串: " + dateStringWithZone);
System.out.println("转换后的 Date 对象: " + date);
// 输出的是本地时区(CST)的时间,但内部存储的是UTC时间戳
} catch (ParseException e) {
e.printStackTrace();
}
}
}
使用 java.time 包 (Java 8 及之后版本 - 推荐)
自 Java 8 起,Java 引入了全新的 java.time 包,它取代了旧的 Date 和 Calendar 类,新 API 更现代、更安全(线程安全)、更易于使用。

(图片来源网络,侵删)
- 核心类:
LocalDate: 表示一个日期(年、月、日),不包含时间。LocalTime: 表示一个时间(时、分、秒、纳秒),不包含日期。LocalDateTime: 表示一个日期和时间,不包含时区信息。ZonedDateTime: 表示一个带时区的日期和时间。DateTimeFormatter: 用于解析和格式化日期时间对象,它是线程安全的。
示例 1:转换为 LocalDateTime
这是最常用的转换之一。
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public DateTimeFormatterExample {
public static void main(String[] args) {
// 1. 定义日期字符串和格式模板
String dateString = "2025-10-27 15:45:30";
String pattern = "yyyy-MM-dd HH:mm:ss";
// 2. 创建 DateTimeFormatter 对象 (它是线程安全的,可以复用)
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
try {
// 3. 调用 parse 方法进行转换
LocalDateTime dateTime = LocalDateTime.parse(dateString, formatter);
// 4. 输出结果
System.out.println("原始字符串: " + dateString);
System.out.println("转换后的 LocalDateTime 对象: " + dateTime);
System.out.println("年份: " + dateTime.getYear());
System.out.println("月份: " + dateTime.getMonth());
System.out.println("日: " + dateTime.getDayOfMonth());
System.out.println("小时: " + dateTime.getHour());
// 5. 格式化回字符串
String formattedDateTime = dateTime.format(formatter);
System.out.println("格式化后的字符串: " + formattedDateTime);
} catch (Exception e) {
System.err.println("日期字符串格式不匹配!请检查字符串和格式模板。");
e.printStackTrace();
}
}
}
输出:
原始字符串: 2025-10-27 15:45:30
转换后的 LocalDateTime 对象: 2025-10-27T15:45:30
年份: 2025
月份: OCTOBER
日: 27
小时: 15
格式化后的字符串: 2025-10-27 15:45:30
示例 2:转换为 ZonedDateTime (带时区)
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public ZonedDateTimeExample {
public static void main(String[] args) {
// 字符串中包含时区信息
String dateStringWithZone = "2025-10-27T10:30:00+08:00[Asia/Shanghai]";
// 使用预定义的 ISO 格式,可以自动解析带时区的字符串
DateTimeFormatter isoFormatter = DateTimeFormatter.ISO_ZONED_DATE_TIME;
try {
ZonedDateTime zonedDateTime = ZonedDateTime.parse(dateStringWithZone, isoFormatter);
System.out.println("原始字符串: " + dateStringWithZone);
System.out.println("转换后的 ZonedDateTime 对象: " + zonedDateTime);
System.out.println("时区: " + zonedDateTime.getZone());
} catch (Exception e) {
e.printStackTrace();
}
}
}
示例 3:java.time 转换为旧的 java.util.Date
如果你需要与一些旧的 API 交互,可能需要将新的日期类型转换为旧的 Date 对象。
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date;
public ToLegacyDateExample {
public static void main(String[] args) {
// 创建一个 java.time 的 ZonedDateTime
ZonedDateTime zdt = ZonedDateTime.of(2025, 10, 27, 10, 30, 0, 0, ZoneId.of("Asia/Shanghai"));
// 转换为 Instant
(图片来源网络,侵删)
