Skip to content

Instant

什么是 Instant?

Instant 表示时间线上的一个瞬时点,类似于 Unix 时间戳,精确到纳秒。

你可以把 Instant 理解为「从 1970-01-01T00:00:00Z 开始过了多少秒/纳秒」,常用于记录事件发生的时间、计算时间差、或者存储到数据库的时间戳。

基本概念

时间线模型

1970-01-01T00:00:00Z                    现在                   未来
      |←─────────────── elapsed ───────────────→|
      |←── epoch seconds ────────────────────→|
      |←── epoch millis ──────────────────→|
      |←── epoch nanos ───────────────→|

Instant 的零点是 Unix Epoch:1970 年 1 月 1 日 00:00:00 UTC。

与 Date 的对比

方面DateInstant
精度毫秒纳秒
时区有时区概念UTC 为基准
线程安全
API 清晰度混乱清晰

基本用法

创建

java
// 当前时刻
Instant now = Instant.now();
System.out.println(now); // 2026-03-22T06:30:45.123456789Z

// 从时间戳创建
Instant ofEpochSecond = Instant.ofEpochSecond(1709454645);
Instant ofEpochMilli = Instant.ofEpochMilli(1709454645123L);
Instant ofEpochNano = Instant.ofEpochSecond(0, 123_456_789); // 第二参数是纳秒

// 从字符串解析
Instant parsed = Instant.parse("2026-03-22T14:30:00Z");

获取值

java
Instant instant = Instant.now();

instant.getEpochSecond();    // 秒(从 1970 到现在)
instant.toEpochMilli();      // 毫秒
instant.getNano();           // 纳秒部分的余数(0-999,999,999)

计算

java
Instant now = Instant.now();

// 加减
Instant later = now.plusSeconds(3600);      // 1 小时后
Instant earlier = now.minusSeconds(3600);   // 1 小时前
Instant later = now.plus(Duration.ofDays(1));  // 1 天后
Instant later = now.plus(1, ChronoUnit.DAYS);  // 同上

// 时间差
Duration diff = Duration.between(instant1, instant2);
long seconds = diff.getSeconds();
long millis = diff.toMillis();

与其他类型转换

与 Date

java
// Instant → Date
Instant instant = Instant.now();
Date date = Date.from(instant);

// Date → Instant
Date date = new Date();
Instant instant = date.toInstant();

与 LocalDateTime

java
// Instant → LocalDateTime(需要时区)
LocalDateTime ldt = LocalDateTime.ofInstant(
    instant, ZoneId.systemDefault());

// LocalDateTime → Instant
LocalDateTime ldt = LocalDateTime.now();
Instant instant = ldt.toInstant(ZoneOffset.UTC);

与 LocalDate

Instant 本身不直接关联日期,需要转换:

java
Instant instant = Instant.now();
LocalDate date = instant.atZone(ZoneId.systemDefault()).toLocalDate();

与 String(格式化)

java
// 使用 DateTimeFormatter
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
    .withZone(ZoneId.systemDefault());

String formatted = formatter.format(instant); // 2026-03-22 14:30:00

// ISO 格式
String iso = instant.toString(); // 2026-03-22T14:30:00.123456789Z

实际应用

记录事件时间

java
public class Event {
    private String name;
    private Instant occurredAt;

    public Event(String name) {
        this.name = name;
        this.occurredAt = Instant.now();
    }
}

计算执行时间

java
public static long measure(Runnable task) {
    Instant start = Instant.now();
    task.run();
    Instant end = Instant.now();
    return Duration.between(start, end).toMillis();
}

// 使用
long millis = measure(() -> {
    // 要测量的代码
    Arrays.sort(new int[10000]);
});

比较时间

java
Instant earlier = Instant.parse("2026-01-01T00:00:00Z");
Instant later = Instant.parse("2026-12-31T23:59:59Z");

boolean isBefore = earlier.isBefore(later);   // true
boolean isAfter = earlier.isAfter(later);    // false
boolean isEqual = earlier.isAfter(earlier); // false,自己和自己比

线程安全

Instant 是不可变且线程安全的:

java
public class TimestampManager {
    // 可以安全地作为静态常量
    private static final Instant EPOCH = Instant.EPOCH;

    public static Instant getTimestamp() {
        return Instant.now(); // 每次返回新实例
    }
}

总结

什么时候用 Instant:

场景推荐
记录事件时间戳Instant
计算时间差Duration + Instant
数据库时间存储Instant / Long 时间戳
需要显示给用户LocalDateTime / ZonedDateTime

记住:Instant 是「时间线上的一个点」,它回答的是「这是什么时候」这个问题,但不关心「是哪天」或「几点几分」这种人类友好的表达。

基于 VitePress 构建