Java 日期处理:LocalDateTime 与 DateTimeFormatter
Java 8 引入的 java.time 包彻底改变了日期时间的处理方式。其中,LocalDateTime 和 DateTimeFormatter 是最常用的两个类。前者用于表示不含时区的日期和时间,后者用于格式化或解析日期时间字符串。掌握它们能让你轻松应对绝大多数日常开发中的日期需求。
创建 LocalDateTime 对象
创建当前系统时间的 LocalDateTime 实例:
LocalDateTime now = LocalDateTime.now();
指定具体的年、月、日、时、分、秒来构建对象:
LocalDateTime specific = LocalDateTime.of(2024, 6, 15, 14, 30, 45);
参数顺序为:年(int)、月(int)、日(int)、小时(int)、分钟(int)、秒(int)。你也可以只传到分钟:
LocalDateTime withoutSeconds = LocalDateTime.of(2024, 6, 15, 14, 30);
从字符串解析成 LocalDateTime(需配合 DateTimeFormatter,详见下文)。
格式化 LocalDateTime 为字符串
默认的 toString() 方法输出类似 2024-06-15T14:30:45 的 ISO 格式。但实际项目中通常需要自定义格式,比如 2024年06月15日 14:30。
使用 DateTimeFormatter 定义格式模板:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm");
String formatted = now.format(formatter);
关键点在于 ofPattern 中的模式字符串。常用符号如下:
| 符号 | 含义 | 示例 |
|---|---|---|
| yyyy | 四位年份 | 2024 |
| MM | 两位月份 | 06 |
| dd | 两位日期 | 15 |
| HH | 24小时制小时 | 14 |
| mm | 分钟 | 30 |
| ss | 秒 | 45 |
注意:MM 必须大写,小写 mm 表示分钟;HH 是 24 小时制,hh 是 12 小时制。
直接链式调用简化代码:
String result = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
从字符串解析为 LocalDateTime
当你收到一个字符串如 "2024-06-15 14:30",需要转成 LocalDateTime 对象以便计算或存储。
先定义与字符串结构完全匹配的 DateTimeFormatter:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
再调用 LocalDateTime.parse() 方法:
LocalDateTime parsed = LocalDateTime.parse("2024-06-15 14:30", formatter);
⚠️ 注意:字符串必须严格符合格式。例如,若字符串是 "2024/06/15 14:30",但格式写成 "yyyy-MM-dd HH:mm",会抛出 DateTimeParseException。
处理常见格式可直接使用预定义常量,避免手写模式:
// ISO_LOCAL_DATE_TIME 对应 "2024-06-15T14:30:45"
LocalDateTime dt = LocalDateTime.parse("2024-06-15T14:30:45", DateTimeFormatter.ISO_LOCAL_DATE_TIME);
// 如果字符串正好是 ISO 格式,甚至可以省略 formatter
LocalDateTime dt2 = LocalDateTime.parse("2024-06-15T14:30:45");
处理中文环境下的格式问题
当格式中包含中文(如“年”“月”),DateTimeFormatter 默认使用系统本地化设置。但在某些服务器环境(如 Linux 默认 locale 为 C),可能无法正确识别中文字符。
显式指定本地化以确保兼容性:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日")
.withLocale(Locale.CHINA);
这样即使在非中文系统上也能正确解析或格式化含中文的日期字符串。
常见错误与避坑指南
- 混淆大小写:
MM(月份)和mm(分钟)极易写错。检查模式字符串是否大小写正确。 - 忽略时区:
LocalDateTime不包含时区信息。如果业务涉及时区转换(如用户在不同时区),应改用ZonedDateTime或OffsetDateTime。 - 格式不匹配:解析时字符串与模式必须一一对应。空格、冒号、连字符都不能多也不能少。
- 线程安全:
DateTimeFormatter是不可变且线程安全的,可定义为static final全局复用:
public class DateUtils {
public static final DateTimeFormatter CHINESE_FORMATTER =
DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm").withLocale(Locale.CHINA);
}
实战:封装常用工具方法
创建一个工具类,集中管理常用格式:
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class DateTimeUtil {
private static final DateTimeFormatter STANDARD =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
private static final DateTimeFormatter CHINESE =
DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm").withLocale(Locale.CHINA);
public static String formatStandard(LocalDateTime dateTime) {
return dateTime.format(STANDARD);
}
public static String formatChinese(LocalDateTime dateTime) {
return dateTime.format(CHINESE);
}
public static LocalDateTime parseStandard(String text) {
return LocalDateTime.parse(text, STANDARD);
}
public static LocalDateTime parseChinese(String text) {
return LocalDateTime.parse(text, CHINESE);
}
}
调用示例:
LocalDateTime now = LocalDateTime.now();
String s1 = DateTimeUtil.formatStandard(now); // "2024-06-15 14:30:45"
String s2 = DateTimeUtil.formatChinese(now); // "2024年06月15日 14:30"
LocalDateTime dt1 = DateTimeUtil.parseStandard("2024-06-15 14:30:45");
LocalDateTime dt2 = DateTimeUtil.parseChinese("2024年06月15日 14:30");
暂无评论,快来抢沙发吧!