> 技术文档 > 【Java第46集】java Instant类详解

【Java第46集】java Instant类详解


文章目录

  • 一、核心特性
  • 二、创建 `Instant` 实例
    • 1. `now()`:获取当前时间的 `Instant`
    • 2. `ofEpochSecond(long epochSecond)`:通过秒数创建
    • 3. `ofEpochMilli(long epochMilli)`:通过毫秒数创建
    • 4. `parse(CharSequence text)`:解析字符串为 `Instant`
  • 三、获取时间戳属性
    • 1. 获取秒数
    • 2. 获取毫秒数
    • 3. 获取纳秒数
  • 四、时间加减操作
    • 1. `plusSeconds(long seconds)` / `minusSeconds(long seconds)`
    • 2. `plus(Duration duration)` / `minus(Duration duration)`
  • 五、与其他时间类的转换
    • 1. 转换为 `LocalDateTime`(需指定时区
    • 2. 转换为 `ZonedDateTime`
    • 3. 转换为 `Date`
    • 4. 从 `Date` 转换为 `Instant`
  • 六、时间比较
    • 1. `isBefore(Instant other)` / `isAfter(Instant other)`
    • 2. `equals(Instant other)`:判断是否相等
  • 七、特殊常量与边界值
    • 1. `EPOCH`:Unix 纪元起点
    • 2. `MIN` / `MAX`:时间范围边界
  • 八、格式化与解析
    • 1. 格式化为字符串
    • 2. 自定义格式解析
  • 九、常见用例示例
    • 1. 记录代码执行时间
    • 2. 跨时区时间转换
    • 3. 处理历史时间戳
  • 十、完整代码示例
  • 十一、总结

Instant 是 Java 8 引入的日期时间 API 中的一个核心类,用于表示 时间线上的一个瞬时点(以 Unix 纪元 1970-01-01T00:00:00Z 为起点)。它是不可变的(线程安全),适用于记录时间戳、性能分析、跨时区事件处理等场景。以下是关于Instant的详细介绍:

一、核心特性

  1. 不可变性
    • 所有操作(如加减、调整)都会返回新对象,原对象保持不变。
  2. 线程安全
    • 由于不可变性,无需同步即可安全使用。
  3. 高精度
    • 支持纳秒级精度(getNano() 方法)。
  4. UTC 时间
    • 默认以 UTC 时区表示时间,不包含时区信息。
  5. 与传统类的兼容性
    • 可与 DateLocalDateTimeZonedDateTime 等类互转。

二、创建 Instant 实例

1. now():获取当前时间的 Instant

Instant now = Instant.now();System.out.println(\"当前时间: \" + now); // 输出如 2025-05-25T14:34:32.123456789Z

2. ofEpochSecond(long epochSecond):通过秒数创建

Instant fromSeconds = Instant.ofEpochSecond(1716549272);System.out.println(\"从秒数创建: \" + fromSeconds); // 对应 2025-05-25T14:34:32Z

3. ofEpochMilli(long epochMilli):通过毫秒数创建

Instant fromMillis = Instant.ofEpochMilli(1716549272123L);System.out.println(\"从毫秒数创建: \" + fromMillis); // 对应 2025-05-25T14:34:32.123Z

4. parse(CharSequence text):解析字符串为 Instant

Instant parsed = Instant.parse(\"2025-05-25T14:34:32.123Z\");System.out.println(\"解析后的时间: \" + parsed); // 输出相同时间

三、获取时间戳属性

1. 获取秒数

long seconds = now.getEpochSecond(); // 获取自1970-01-01T00:00:00Z以来的秒数System.out.println(\"秒数: \" + seconds);

2. 获取毫秒数

long millis = now.toEpochMilli(); // 获取自1970-01-01T00:00:00Z以来的毫秒数System.out.println(\"毫秒数: \" + millis);

3. 获取纳秒数

int nanos = now.getNano(); // 获取秒内的纳秒部分(0~999,999,999)System.out.println(\"纳秒数: \" + nanos);

四、时间加减操作

1. plusSeconds(long seconds) / minusSeconds(long seconds)

Instant plus10Seconds = now.plusSeconds(10); // 当前时间 + 10秒Instant minus5Seconds = now.minusSeconds(5); // 当前时间 - 5秒System.out.println(\"加10秒: \" + plus10Seconds);System.out.println(\"减5秒: \" + minus5Seconds);

2. plus(Duration duration) / minus(Duration duration)

Duration duration = Duration.ofHours(2); // 2小时Instant plus2Hours = now.plus(duration);Instant minus2Hours = now.minus(duration);System.out.println(\"加2小时: \" + plus2Hours);System.out.println(\"减2小时: \" + minus2Hours);

五、与其他时间类的转换

1. 转换为 LocalDateTime(需指定时区)

LocalDateTime localDateTime = now.atZone(ZoneId.systemDefault()).toLocalDateTime();System.out.println(\"本地时间: \" + localDateTime);

2. 转换为 ZonedDateTime

ZonedDateTime zonedDateTime = now.atZone(ZoneId.of(\"Asia/Shanghai\"));System.out.println(\"带时区的时间: \" + zonedDateTime); // 输出 2025-05-25T22:34:32.123+08:00[Asia/Shanghai]

3. 转换为 Date

Date date = Date.from(now);System.out.println(\"转换为Date: \" + date);

4. 从 Date 转换为 Instant

Instant fromDate = date.toInstant();System.out.println(\"从Date转换: \" + fromDate);

六、时间比较

1. isBefore(Instant other) / isAfter(Instant other)

Instant future = now.plusSeconds(100);boolean isBefore = now.isBefore(future); // trueSystem.out.println(\"是否在目标时间之前: \" + isBefore);

2. equals(Instant other):判断是否相等

Instant sameInstant = now;boolean isEqual = now.equals(sameInstant); // trueSystem.out.println(\"是否相等: \" + isEqual);

七、特殊常量与边界值

1. EPOCH:Unix 纪元起点

Instant epoch = Instant.EPOCH;System.out.println(\"纪元起点: \" + epoch); // 1970-01-01T00:00:00Z

2. MIN / MAX:时间范围边界

Instant minInstant = Instant.MIN; // -10^6 - 1970-01-01T00:00:00ZInstant maxInstant = Instant.MAX; // +10^6 - 1970-01-01T00:00:00ZSystem.out.println(\"最小时间: \" + minInstant);System.out.println(\"最大时间: \" + maxInstant);

八、格式化与解析

1. 格式化为字符串

String formatted = now.toString(); // 默认格式:2025-05-25T14:34:32.123456789ZSystem.out.println(\"格式化后的时间: \" + formatted);

2. 自定义格式解析

DateTimeFormatter formatter = DateTimeFormatter.ofPattern(\"yyyy-MM-dd HH:mm:ss XXX\");Instant customParsed = Instant.parse(\"2025-05-25 14:34:32 +0800\", formatter);System.out.println(\"自定义解析后的时间: \" + customParsed); // 输出 UTC 时间

九、常见用例示例

1. 记录代码执行时间

Instant start = Instant.now();// 执行耗时操作Thread.sleep(1000);Instant end = Instant.now();Duration duration = Duration.between(start, end);System.out.println(\"耗时: \" + duration.toSeconds() + \" 秒\");

2. 跨时区时间转换

Instant utcTime = Instant.now();ZonedDateTime newYorkTime = utcTime.atZone(ZoneId.of(\"America/New_York\"));System.out.println(\"纽约时间: \" + newYorkTime); // 输出如 2025-05-25T08:34:32.123-04:00[America/New_York]

3. 处理历史时间戳

Instant historicalEvent = Instant.ofEpochSecond(-123456); // 1970年之前的事件System.out.println(\"历史事件时间: \" + historicalEvent); // 输出如 -0001-12-01T00:00:00Z

十、完整代码示例

import java.time.*;import java.time.format.DateTimeFormatter;public class InstantExample { public static void main(String[] args) { // 创建Instant Instant now = Instant.now(); System.out.println(\"当前时间: \" + now); // 获取时间戳 long seconds = now.getEpochSecond(); long millis = now.toEpochMilli(); int nanos = now.getNano(); System.out.println(\"秒数: \" + seconds + \", 毫秒数: \" + millis + \", 纳秒数: \" + nanos); // 时间加减 Instant plus10Sec = now.plusSeconds(10); Instant minus5Sec = now.minusSeconds(5); System.out.println(\"加10秒: \" + plus10Sec); System.out.println(\"减5秒: \" + minus5Sec); // 转换为其他时间类 ZonedDateTime zoned = now.atZone(ZoneId.of(\"Asia/Shanghai\")); LocalDateTime local = zoned.toLocalDateTime(); System.out.println(\"本地时间: \" + local); System.out.println(\"带时区的时间: \" + zoned); // 时间比较 Instant future = now.plusSeconds(100); System.out.println(\"是否在目标时间之前: \" + now.isBefore(future)); // 格式化与解析 String formatted = now.toString(); System.out.println(\"格式化后的时间: \" + formatted); DateTimeFormatter formatter = DateTimeFormatter.ofPattern(\"yyyy-MM-dd HH:mm:ss XXX\"); Instant parsed = Instant.parse(\"2025-05-25 14:34:32 +0800\", formatter); System.out.println(\"解析后的时间: \" + parsed); }}

十一、总结

方法 用途 now() / ofEpochSecond() / ofEpochMilli() / parse() 创建 Instant 实例 getEpochSecond() / toEpochMilli() / getNano() 获取时间戳属性 plusSeconds() / minusSeconds() / plus() / minus() 时间加减操作 atZone() / toLocalDateTime() / from(Date) 转换为其他时间类 isBefore() / isAfter() / equals() 时间比较 EPOCH / MIN / MAX 特殊时间点
  • 优势
    • 高精度:支持纳秒级时间戳,适合高性能场景。
    • 线程安全:不可变设计避免并发问题。
    • 兼容性:与 DateLocalDateTime 等无缝集成。
    • 跨时区处理:通过 atZone() 自动适配时区。