421. Java 日期时间 API - 包结构 & 方法命名规范
1. Date-Time API 的包结构 🗂️
Java 的 Date-Time API 主要由一个核心包和四个子包组成:
1.1 java.time(核心包)
这是整个 API 的核心,提供最常用的类:
-
LocalDate→ 只包含日期 -
LocalTime→ 只包含时间 -
LocalDateTime→ 日期 + 时间(不带时区) -
ZonedDateTime→ 带时区的日期和时间 -
Instant→ 时间戳(精确到纳秒) -
Duration→ 表示两个时间点之间的时长 -
Clock→ 提供访问当前时间和时区的方式
👉 特点:这些类都是基于 ISO-8601 日历系统,不可变(immutable)且线程安全。
示例:
LocalDate today = LocalDate.now();
LocalTime time = LocalTime.now();
LocalDateTime dateTime = LocalDateTime.now();
Instant timestamp = Instant.now();
System.out.println("今天: " + today);
System.out.println("现在的时间: " + time);
System.out.println("当前日期时间: " + dateTime);
System.out.println("时间戳: " + timestamp);
1.2 java.time.chrono(替代日历系统)
提供 非 ISO-8601 日历,例如:
- Hijrah(伊斯兰历)
- JapaneseDate(日本历法)
- ThaiBuddhistDate(泰国佛历)
你也可以自己定义日历系统(不过很少用)。
示例:
HijrahDate hijrahDate = HijrahDate.now();
System.out.println("伊斯兰历日期: " + hijrahDate);
JapaneseDate japaneseDate = JapaneseDate.now();
System.out.println("日本历日期: " + japaneseDate);
1.3 java.time.format(格式化与解析)
提供日期时间的 格式化(format) 和 解析(parse)。
示例:
LocalDate date = LocalDate.of(2025, 9, 15);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
System.out.println("格式化日期: " + date.format(formatter));
String input = "2025-09-15";
LocalDate parsedDate = LocalDate.parse(input, DateTimeFormatter.ISO_LOCAL_DATE);
System.out.println("解析后的日期: " + parsedDate);
1.4 java.time.temporal(时间操作扩展)
给框架和库开发者用的扩展 API:
-
TemporalField/ChronoField→ 日期时间的字段(比如 YEAR、MONTH、DAY_OF_MONTH) -
TemporalUnit/ChronoUnit→ 时间单位(比如 DAYS、HOURS、MINUTES) - 提供 时间查询(query) 和 调整器(adjuster) 功能
示例:
LocalDate today = LocalDate.now();
int dayOfYear = today.get(ChronoField.DAY_OF_YEAR);
System.out.println("今天是一年的第几天: " + dayOfYear);
LocalDate firstDayOfNextMonth = today.with(TemporalAdjusters.firstDayOfNextMonth());
System.out.println("下个月的第一天: " + firstDayOfNextMonth);
1.5 java.time.zone(时区支持)
提供时区和时区规则的支持。常见类:
ZoneIdZoneOffsetZoneRules
👉 在大多数情况下,我们只需要用到 ZonedDateTime、ZoneId、ZoneOffset。
示例:
ZonedDateTime shanghaiTime = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
ZonedDateTime newYorkTime = ZonedDateTime.now(ZoneId.of("America/New_York"));
System.out.println("上海时间: " + shanghaiTime);
System.out.println("纽约时间: " + newYorkTime);
2. 方法命名规范 📖
Date-Time API 方法的命名非常一致,方便记忆和使用。下面是常见前缀和它们的作用:
| 前缀 | 方法类型 | 用途 |
|---|---|---|
| of | static factory | 创建实例,主要用于校验输入参数,而不是转换 |
| from | static factory | 从另一个对象转换成目标类型,可能会丢失信息 |
| parse | static factory | 把字符串解析为日期时间对象 |
| format | instance | 格式化对象为字符串 |
| get | instance | 获取对象的某部分状态 |
| is | instance | 判断状态(布尔查询) |
| with | instance | 返回修改后的副本(不可变对象的 set 等价物) |
| plus | instance | 返回加上时间量后的副本 |
| minus | instance | 返回减去时间量后的副本 |
| to | instance | 转换为另一种类型 |
| at | instance | 与另一个对象组合 |
2.1 示例讲解 📝
of → 创建对象
LocalDate date = LocalDate.of(2025, 9, 15);
from → 类型转换
Instant instant = Instant.now();
ZonedDateTime zoned = ZonedDateTime.from(instant.atZone(ZoneId.systemDefault()));
parse → 字符串解析
LocalDate parsed = LocalDate.parse("2025-09-15");
format → 格式化输出
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
String formatted = LocalDate.now().format(formatter);
get / is → 获取或判断
int day = LocalDate.now().getDayOfMonth();
boolean leap = LocalDate.now().isLeapYear();
with → 修改值(返回新对象)
LocalDate changed = LocalDate.now().withMonth(12);
plus / minus → 加减操作
LocalDate future = LocalDate.now().plusDays(10);
LocalDate past = LocalDate.now().minusWeeks(2);
to → 转换
LocalDateTime ldt = LocalDateTime.now();
Instant inst = ldt.toInstant(ZoneOffset.UTC);
at → 组合
LocalDate today = LocalDate.now();
LocalTime time = LocalTime.of(14, 30);
LocalDateTime combined = today.atTime(time);
总结 🎯
-
包结构:核心用
java.time,复杂需求可扩展到chrono、format、temporal、zone。 -
方法规范:命名规则统一,便于记忆;常见操作用
of、with、plus、minus、parse、format。 -
实际开发建议:优先使用
java.time包下的类,比如LocalDateTime、ZonedDateTime,同时掌握DateTimeFormatter来处理输入输出。