430. Java 日期时间 API - 时间计算 Temporal 包

文章目录

  • [430. Java 日期时间 API - 时间计算 Temporal 包](#430. Java 日期时间 API - 时间计算 Temporal 包)
    • [1. 为什么需要 Temporal 包?](#1. 为什么需要 Temporal 包?)
    • [2. 核心接口](#2. 核心接口)
      • [2.1 Temporal 和 TemporalAccessor](#2.1 Temporal 和 TemporalAccessor)
      • [2.2 TemporalField 与 TemporalUnit](#2.2 TemporalField 与 TemporalUnit)
    • [3. ChronoField 和 IsoFields](#3. ChronoField 和 IsoFields)
    • [4. ChronoUnit ------ 时间单位](#4. ChronoUnit —— 时间单位)
    • [5. TemporalAmount ------ 时间量](#5. TemporalAmount —— 时间量)
    • [6. 小结 🎯](#6. 小结 🎯)

430. Java 日期时间 API - 时间计算 Temporal 包

今天我们要学习的是 java.time.temporal 包。它提供了一组 接口、类和枚举 ,专门用来支持日期和时间的底层操作,特别是各种 时间计算


1. 为什么需要 Temporal 包?

大家先想一个问题:

👉 我们平时用的 LocalDateLocalDateTimeZonedDateTime 已经很强大了,为什么还要搞一个 Temporal 包?

答案是:这些类在底层 都遵循统一的接口(Temporal、TemporalAccessor 等) ,所以无论我们是加一天、减一小时、还是取出某个字段,都可以用 同一套规则来处理

这就像写代码时:

  • 大部分时候我们直接用 String(具体类)。
  • 但底层其实都实现了 CharSequence(接口)。

2. 核心接口

2.1 Temporal 和 TemporalAccessor

  • Temporal
    • 可读可写(支持加减时间)
    • 实现类:InstantLocalDateTimeZonedDateTime
    • 提供统一的时间计算方法,例如:plus()minus()
  • TemporalAccessor
    • 只读版本,只能获取值,不能修改。

👉 打个比方:

  • Temporal 就像一个 可以调表针的钟表
  • TemporalAccessor 就像一个 只能看时间的钟表

2.2 TemporalField 与 TemporalUnit

  • TemporalField :表示时间的"字段"
    • 例如:天、月、年、星期几
    • 具体实现:ChronoField 枚举
  • TemporalUnit :表示时间的"单位"
    • 例如:秒、分钟、小时、天、年
    • 具体实现:ChronoUnit 枚举

⚡ 举个例子:

java 复制代码
LocalDate date = LocalDate.now();

// 取出当年的第几天
int dayOfYear = date.get(ChronoField.DAY_OF_YEAR);
System.out.println("今天是今年的第 " + dayOfYear + " 天");

// 取出第几季度(IsoFields 提供)
int quarter = date.get(IsoFields.QUARTER_OF_YEAR);
System.out.println("现在是第 " + quarter + " 季度");

3. ChronoField 和 IsoFields

  • ChronoField
    提供了大量常用的日期时间字段,例如:
    • DAY_OF_YEAR → 一年中的第几天
    • CLOCK_HOUR_OF_DAY → 一天中的第几小时(1-24)
    • MINUTE_OF_HOUR → 当前小时的第几分钟
  • IsoFields
    补充了一些 ISO-8601 规范里的字段,比如:
    • QUARTER_OF_YEAR → 一年中的第几季度

📌 示例:

java 复制代码
LocalDate today = LocalDate.now();

// 检查 LocalDate 是否支持 "小时" 字段
boolean isSupported = today.isSupported(ChronoField.CLOCK_HOUR_OF_DAY);
System.out.println("LocalDate 是否支持小时字段? " + isSupported);  // false

// 获取毫秒数(通过 ChronoField)
LocalTime time = LocalTime.now();
int millis = time.get(ChronoField.MILLI_OF_SECOND);
System.out.println("当前毫秒数: " + millis);

// 获取季度(通过 IsoFields)
int q = today.get(IsoFields.QUARTER_OF_YEAR);
System.out.println("当前季度: Q" + q);

4. ChronoUnit ------ 时间单位

ChronoUnit 是时间单位的标准枚举,从 纳秒千年 ,都有定义。

比如:

  • ChronoUnit.SECONDS
  • ChronoUnit.MINUTES
  • ChronoUnit.DAYS
  • ChronoUnit.YEARS
  • ChronoUnit.MILLENNIA(千年 🚀)

⚠️ 但是!

不是所有类都支持所有单位。

📌 示例:

java 复制代码
Instant instant = Instant.now();

// 检查是否支持"天"这个单位
boolean supported = instant.isSupported(ChronoUnit.YEARS);
System.out.println("Instant 是否支持按天操作? " + supported);  // false

为什么返回 false?

因为 Instant绝对时间点(机器时间),它只能理解秒、纳秒这些精确单位,但不懂"年"这种人类时间概念。


5. TemporalAmount ------ 时间量

时间加减需要一个"数量",由 TemporalAmount 接口 定义。

常见实现类有:

  • Duration → 精确到秒/纳秒(适合机器时间)
  • Period → 年/月/日(适合人类日历)

📌 示例:

java 复制代码
LocalDate today = LocalDate.now();

// 用 Period 加 1 个月
LocalDate nextMonth = today.plus(Period.ofMonths(1));
System.out.println("一个月后: " + nextMonth);

// 用 Duration 加 1 小时
LocalDateTime now = LocalDateTime.now();
LocalDateTime oneHourLater = now.plus(Duration.ofHours(1));
System.out.println("一小时后: " + oneHourLater);

6. 小结 🎯

概念 接口/类 举例
时间对象 Temporal, TemporalAccessor LocalDate, Instant
时间字段 TemporalField, ChronoField DAY_OF_YEAR, CLOCK_HOUR_OF_DAY
时间单位 TemporalUnit, ChronoUnit SECONDS, DAYS, MILLENNIA
时间量 TemporalAmount, Period, Duration Period.ofMonths(1), Duration.ofHours(2)

记忆方法

  • Field → 字段(是什么) → 年、月、日
  • Unit → 单位(以什么度量) → 天、小时、秒
  • Amount → 时间量(加减多少) → 3 天、2 小时
相关推荐
RSTJ_16251 小时前
PYTHON+AI LLM DAY SEVENTY
人工智能·python·深度学习
财经资讯数据_灵砚智能1 小时前
基于全球经济类多源新闻的NLP情感分析与数据可视化(日间)2026年6月8日
大数据·人工智能·python·ai·信息可视化·自然语言处理·灵砚智能
星马梦缘1 小时前
数据库 第十三章 未完结版本
java·网络·数据库
程序猿乐锅1 小时前
【JAVASE | 第十六篇】多线程
java·开发语言
Cobyte1 小时前
18.【SolidJS】 采用 template 内容模板元素创建 DOM 元素
前端·javascript·vue.js
做个文艺程序员1 小时前
第01篇:Redis 从入门到上手:核心数据结构与 Java Spring Boot 实战详解
java·redis数据结构·redis入门·redis教程·java集成redis
m沐沐1 小时前
数据集的六种填充方法——下(使用众数填充+使用逻辑回归填充+使用随机森林填充)
python·随机森林·机器学习·pycharm·逻辑回归
TonyLee0171 小时前
AutoDL租卡记录
服务器·python
m沐沐1 小时前
【机器学习】7 种分类模型实战(逻辑回归→随机森林→SVM→AdaBoost→朴素贝叶斯→XGBoost→神经网络)
人工智能·pytorch·python·随机森林·机器学习·分类·逻辑回归