前言:
在 Java 中,日期(Date/Time)和字符串(String)之间的转换是开发中最常见的操作之一。
随着 Java 版本的演进,处理方式发生了巨大变化。强烈建议使用 Java 8 引入的 java.time 包(新日期 API),它比旧的 java.util.Date 更安全、更简洁、线程安全。
🚀 推荐方案:Java 8+ (java.time)
这是现代 Java 开发的标准做法。
主要涉及三个类:
1.LocalDateTime : 本地日期时间(最常用,如 2023-10-27T10:30:00)。
2.LocalDate : 仅日期(如 2023-10-27)。
3.DateTimeFormatter: 格式化工具(线程安全,替代旧的 SimpleDateFormat)。
1. 字符串 ➡️ 日期 (String to Date)
java
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class DateDemo {
public static void main(String[] args) {
// 定义格式:年-月-日 时:分:秒
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String dateStr = "2023-10-27 14:30:00";
// 解析字符串为 LocalDateTime
LocalDateTime localDateTime = LocalDateTime.parse(dateStr, formatter);
System.out.println(localDateTime);
// 输出: 2023-10-27T14:30
}
}
注意⚠️:如果字符串格式与 ofPattern 不完全匹配(比如多了一个空格),会抛出 DateTimeParseException。
2. 日期 ➡️ 字符串 (Date to String)
java
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class DateDemo {
public static void main(String[] args) {
LocalDateTime now = LocalDateTime.now();
// 定义格式
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
// 格式化日期为字符串
String dateStr = now.format(formatter);
System.out.println(dateStr);
// 输出: 2023/10/27 14:35:12
}
}
3. 常见格式模式符号
| 符号 | 含义 | 示例 |
|---|---|---|
| y | 年 | yyyy -> 2023 |
| M | 月 | MM -> 10, MMM -> Oct |
| d | 日 | dd -> 27 |
| H | 时(24小时制) | H 时 (24小时制) HH -> 14 |
| h | 时(12小时制) | h 时 (12小时制) hh -> 02 |
| m | 分 | mm -> 30 |
| s | 秒 | ss -> 00 |
| S | 毫秒 | SSS -> 123 |
⚠️ 旧方案:Java 8 之前 (java.util.Date)
如果你维护老项目,可能会遇到 Date 和 SimpleDateFormat。
❌ 缺点:
- 线程不安全:SimpleDateFormat 在多线程环境下会出错,必须每次 new 一个或使用 ThreadLocal。
- API难用:月份从 0 开始(1月是 0),年份从 1900 开始计算等
示例(不推荐,但需了解):
java
import java.text.SimpleDateFormat;
import java.util.Date;
// 1. Date -> String
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String str = sdf.format(date);
// 2. String -> Date
String dateStr = "2023-10-27 14:30:00";
Date parsedDate = sdf.parse(dateStr); // 需要处理 ParseException
计算时间差的例子(Java 8):
java
LocalDateTime start = LocalDateTime.of(2023, 10, 1, 10, 0);
LocalDateTime end = LocalDateTime.of(2023, 10, 5, 12, 0);
long days = java.time.temporal.ChronoUnit.DAYS.between(start, end);
System.out.println("相差天数: " + days); // 输出: 4
下面的实战可以不看---------------------------------------------------------------------------------------------------------------
实战场景(针对TodoList案例)
通常不需要手动转换,因为框架会自动处理。
1. 数据库字段类型建议
MySQL 中使用 DATETIME 或 TIMESTAMP。
Java 实体类中使用 LocalDateTime。
java
@Data
@TableName("todo")
public class Todo {
@TableId
private Long id;
private String title;
// MP 会自动将数据库的 DATETIME 映射为 LocalDateTime
private LocalDateTime createTime;
private LocalDateTime updateTime;
}
2. 前端传参(JSON)
前端通常传递字符串格式的日期,如 "2023-10-27T14:30:00" 或 "2023-10-27 14:30:00"。
Spring Boot 默认支持 ISO 格式(yyyy-MM-dd'T'HH:mm:ss)。如果前端传的是自定义格式(如 yyyy-MM-dd HH:mm:ss),你需要配置全局转换器:
方式一:在 application.yml 中配置(推荐)
yaml
spring:
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
方式二:使用注解(针对特定字段)
java
@Data
public class CreateTodoDTO {
private String title;
// 指定反序列化时的格式
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime expectedTime;
}
总结:
- 新项目开发 全程使用 java.time.LocalDateTime + DateTimeFormatter
- 老项目维护 尽量重构为Java 8 时间 API;若不能,注意 SimpleDateFormat 的线程安全问题
- 数据库交互 实体类用LocalDateTime,MP 自动映射
- 前后端交互 统一使用 ISO 8601 格式或配置 Jackson 全局格式
- 计算时间差 使用Duration.between(start, end) 或 ChronoUnit.DAYS.between(d1, d2)