跳转到内容

Java日期时间格式化

来自代码酷

模板:Note

Java日期时间格式化[编辑 | 编辑源代码]

Java日期时间格式化是将日期或时间对象转换为可读字符串(格式化)或反向解析的过程。Java 8引入的`java.time.format.DateTimeFormatter`类提供了线程安全且灵活的格式化工具,取代了旧版`SimpleDateFormat`。

核心概念[编辑 | 编辑源代码]

格式化与解析[编辑 | 编辑源代码]

  • 格式化:将`LocalDate`、`LocalDateTime`等对象 → 字符串(如`"2023-12-25"`)
  • 解析:将字符串 → 日期时间对象

预定义格式器[编辑 | 编辑源代码]

Java提供了三种常用格式器:

// 预定义常量示例
DateTimeFormatter.ISO_LOCAL_DATE      // 格式:2023-12-31
DateTimeFormatter.ISO_LOCAL_TIME      // 格式:23:59:59.999
DateTimeFormatter.ISO_LOCAL_DATE_TIME // 格式:2023-12-31T23:59:59.999

基础用法[编辑 | 编辑源代码]

自定义模式[编辑 | 编辑源代码]

通过模式字符串定义格式:

常用模式符号
符号 含义 示例
y 年份 2023 → "23"或"2023"
M 月份 7 → "7"或"07"
d 5 → "5"或"05"
H 小时(24小时制) 15 → "15"
m 分钟 8 → "8"或"08"
s 45 → "45"
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime now = LocalDateTime.now();

// 格式化
String formatted = now.format(formatter); // 输出如:"2023-08-15 14:30:45"

// 解析
LocalDateTime parsed = LocalDateTime.parse("2023-08-15 14:30:45", formatter);

本地化格式[编辑 | 编辑源代码]

结合`Locale`实现地区特定显示:

DateTimeFormatter frenchFormatter = DateTimeFormatter
    .ofPattern("EEEE, d MMMM yyyy", Locale.FRENCH);
String frenchDate = LocalDate.now().format(frenchFormatter);
// 输出:"mercredi, 15 août 2023"

高级特性[编辑 | 编辑源代码]

格式器构建器[编辑 | 编辑源代码]

使用`DateTimeFormatterBuilder`实现复杂格式:

DateTimeFormatter complexFormatter = new DateTimeFormatterBuilder()
    .appendLiteral("订单创建时间:")
    .appendValue(ChronoField.YEAR)
    .appendLiteral("/")
    .appendValue(ChronoField.MONTH_OF_YEAR)
    .appendLiteral("/")
    .appendValue(ChronoField.DAY_OF_MONTH)
    .appendLiteral(" ")
    .appendValue(ChronoField.HOUR_OF_DAY)
    .appendLiteral("时")
    .toFormatter();
// 输出示例:"订单创建时间:2023/8/15 14时"

解析宽松模式[编辑 | 编辑源代码]

处理非严格匹配的输入:

DateTimeFormatter lenientFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
    .withResolverStyle(ResolverStyle.LENIENT);
LocalDate.parse("2023-02-30", lenientFormatter); // 自动调整为2023-03-02

新旧API对比[编辑 | 编辑源代码]

`DateTimeFormatter` vs `SimpleDateFormat`
特性 新API 旧API
线程安全 ✔️ 是 ❌ 否
默认严格解析 ✔️ 是 ❌ 否
支持纳秒 ✔️ 是 ❌ 仅到毫秒

旧版代码示例(不推荐新项目使用):

SimpleDateFormat oldFormatter = new SimpleDateFormat("yyyy-MM-dd");
Date oldDate = oldFormatter.parse("2023-08-15"); // 返回java.util.Date

实际应用案例[编辑 | 编辑源代码]

案例1:日志时间戳格式化[编辑 | 编辑源代码]

DateTimeFormatter logFormatter = DateTimeFormatter.ofPattern("[yyyy-MM-dd HH:mm:ss.SSS]");
System.out.println(logFormatter.format(LocalDateTime.now()) + " 用户登录成功");
// 输出示例:[2023-08-15 14:30:45.123] 用户登录成功

案例2:多语言日期显示[编辑 | 编辑源代码]

pie title 多语言日期格式使用场景 "英文界面" : 45 "中文界面" : 30 "其他语言" : 25

public String getLocalizedDate(LocalDate date, Locale locale) {
    return date.format(DateTimeFormatter
        .ofLocalizedDate(FormatStyle.LONG)
        .withLocale(locale));
}
// 调用示例:
// getLocalizedDate(LocalDate.now(), Locale.US) → "August 15, 2023"
// getLocalizedDate(LocalDate.now(), Locale.CHINA) → "2023年8月15日"

常见问题[编辑 | 编辑源代码]

问题1:解析失败处理[编辑 | 编辑源代码]

使用`DateTimeParseException`处理错误输入:

try {
    LocalDate.parse("2023/08/15", DateTimeFormatter.ISO_LOCAL_DATE);
} catch (DateTimeParseException e) {
    System.err.println("日期格式错误,请使用yyyy-MM-dd格式");
}

问题2:时区处理[编辑 | 编辑源代码]

格式化带时区的时间:

ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("America/New_York"));
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss z");
// 输出:"2023-08-15 02:30:45 EDT"

最佳实践[编辑 | 编辑源代码]

1. 对于频繁使用的格式器,应声明为`static final`常量 2. 优先使用`ISO-8601`标准格式(如`2023-08-15T14:30:45Z`)进行数据交换 3. 用户界面显示时再转换为本地化格式 4. 时间戳存储推荐使用`Instant`类型

页面模块:Message box/ambox.css没有内容。

延伸学习[编辑 | 编辑源代码]

  • 日期时间算术运算(如`plusDays()`、`minusHours()`)
  • 时区转换(`ZoneId`和`ZonedDateTime`)
  • 时间段计算(`Period`和`Duration`)