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 的对比
| 方面 | Date | Instant |
|---|---|---|
| 精度 | 毫秒 | 纳秒 |
| 时区 | 有时区概念 | 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 是「时间线上的一个点」,它回答的是「这是什么时候」这个问题,但不关心「是哪天」或「几点几分」这种人类友好的表达。
