Java Instant 类
最后修改时间:2025 年 4 月 16 日
java.time.Instant 类表示 UTC 时间线上的一个点。它从 1970-01-01T00:00:00Z 的 epoch 开始测量时间。Instant 提供了纳秒精度来表示时间戳。
Instant 是不可变的且线程安全的。它通常用于记录事件、在数据库中存储时间戳以及测量时间间隔。该类使用机器时间,而不是像日期这样的时间概念。
Instant 类概述
Instant 提供了获取当前时间、解析字符串和执行计算的方法。关键操作包括比较 Instant、添加持续时间以及转换为其他时间类型。该类处理秒和纳秒的时间。
public final class Instant implements Temporal, TemporalAdjuster,
Comparable<Instant>, Serializable {
public static Instant now();
public static Instant ofEpochSecond(long epochSecond);
public static Instant ofEpochMilli(long epochMilli);
public static Instant parse(CharSequence text);
public long getEpochSecond();
public int getNano();
public boolean isAfter(Instant otherInstant);
public boolean isBefore(Instant otherInstant);
public Instant plus(long amountToAdd, TemporalUnit unit);
public Instant minus(long amountToSubtract, TemporalUnit unit);
}
上面的代码显示了 Instant 提供的关键方法。这些方法允许创建、比较和操作 Instant。该类提供高达纳秒的精度,同时保持与旧 API 的兼容性。
创建 Instant 对象
可以以多种方式创建 Instant 对象。最常见的方法是使用 now 获取当前时间,以及使用工厂方法获取特定的时间点。也支持从字符串解析。
package com.zetcode;
import java.time.Instant;
public class Main {
public static void main(String[] args) {
// Current instant
Instant now = Instant.now();
System.out.println("Current instant: " + now);
// From epoch seconds
Instant epochSec = Instant.ofEpochSecond(1_000_000);
System.out.println("From epoch seconds: " + epochSec);
// From epoch milliseconds
Instant epochMilli = Instant.ofEpochMilli(1_000_000_000L);
System.out.println("From epoch milliseconds: " + epochMilli);
// From string
Instant parsed = Instant.parse("2025-01-01T00:00:00Z");
System.out.println("Parsed from string: " + parsed);
}
}
此示例演示了创建 Instant 对象的不同方法。输出显示 ISO-8601 格式的时间戳。now 方法捕获当前时刻,并尽可能提供纳秒精度。
获取 Instant 组件
一个 Instant 可以分解为它的 epoch 秒和纳秒组件。这些值表示自 1970-01-01T00:00:00Z 以来的时间。这些方法对于与旧 API 的互操作性很有用。
package com.zetcode;
import java.time.Instant;
public class Main {
public static void main(String[] args) {
Instant instant = Instant.now();
// Get epoch seconds
long seconds = instant.getEpochSecond();
System.out.println("Epoch seconds: " + seconds);
// Get nanoseconds fraction
int nanos = instant.getNano();
System.out.println("Nanoseconds: " + nanos);
// Convert to milliseconds (losing nanos precision)
long millis = instant.toEpochMilli();
System.out.println("Epoch milliseconds: " + millis);
}
}
此示例展示了如何从 Instant 中提取组件。请注意,toEpochMilli 失去了纳秒精度,因为它转换为毫秒。epoch 秒和纳秒一起提供了完整的精度。
比较 Instants
可以比较 Instants 以确定时间顺序。该类提供了 isBefore、isAfter 和 compareTo 方法。这些比较对于应用程序中基于时间的逻辑至关重要。
package com.zetcode;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
public class Main {
public static void main(String[] args) {
Instant now = Instant.now();
Instant later = now.plus(1, ChronoUnit.HOURS);
Instant earlier = now.minus(30, ChronoUnit.MINUTES);
System.out.println("Now is before later: " + now.isBefore(later));
System.out.println("Now is after earlier: " + now.isAfter(earlier));
System.out.println("Comparison result: " + now.compareTo(later));
// Equality check
Instant copy = Instant.ofEpochSecond(now.getEpochSecond(), now.getNano());
System.out.println("Now equals copy: " + now.equals(copy));
}
}
此示例演示了比较 Instant 对象的各种方法。比较方法同时考虑了秒和纳秒组件。请注意,相等需要两个组件完全匹配。
添加和减去时间
Instant 通过 plus 和 minus 方法支持时间算术。这些操作对于计算未来或过去的时间点很有用。该类会自动处理溢出和下溢。
package com.zetcode;
import java.time.Instant;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
public class Main {
public static void main(String[] args) {
Instant now = Instant.now();
// Add using ChronoUnit
Instant inOneHour = now.plus(1, ChronoUnit.HOURS);
System.out.println("In one hour: " + inOneHour);
// Subtract using Duration
Instant thirtyMinsAgo = now.minus(Duration.ofMinutes(30));
System.out.println("Thirty minutes ago: " + thirtyMinsAgo);
// Add days (converted to seconds)
Instant tomorrow = now.plus(1, ChronoUnit.DAYS);
System.out.println("Tomorrow: " + tomorrow);
// Mixed operations
Instant complex = now.plus(2, ChronoUnit.HOURS)
.minus(15, ChronoUnit.MINUTES);
System.out.println("Complex operation result: " + complex);
}
}
此示例展示了使用 Instant 执行时间算术的各种方法。操作可以使用 ChronoUnit 常量或 Duration 对象。所有计算都精确到纳秒,并自动处理单位转换。
在时间类型之间转换
Instant 可以转换为其他时间类型,如 ZonedDateTime,也可以从其他时间类型转换。当处理时区或人类可读的日期表示时,这些转换至关重要。
package com.zetcode;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class Main {
public static void main(String[] args) {
Instant now = Instant.now();
// Convert to ZonedDateTime
ZonedDateTime zoned = now.atZone(ZoneId.of("America/New_York"));
System.out.println("In New York: " + zoned);
// Convert to LocalDateTime (loses timezone info)
LocalDateTime local = LocalDateTime.ofInstant(now, ZoneId.systemDefault());
System.out.println("Local date-time: " + local);
// Convert back to Instant
Instant back = zoned.toInstant();
System.out.println("Back to instant: " + back);
// Convert from LocalDateTime
Instant fromLocal = LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant();
System.out.println("From local date-time: " + fromLocal);
}
}
此示例演示了 Instant 和其他时间类型之间的转换。请注意,LocalDateTime 缺少时区信息,因此使用系统默认值。所有转换都保留了所表示的确切时间点。
测量时间间隔
Instant 经常用于测量事件之间的时间间隔。Duration 类与 Instant 配合使用,以提供具有各种单位的精确时间测量。
package com.zetcode;
import java.time.Instant;
import java.time.Duration;
public class Main {
public static void main(String[] args) throws InterruptedException {
Instant start = Instant.now();
// Simulate work
Thread.sleep(1500);
Instant end = Instant.now();
// Calculate duration
Duration duration = Duration.between(start, end);
System.out.println("Elapsed time: " + duration.toMillis() + " ms");
System.out.println("In seconds: " + duration.getSeconds() + "." +
duration.getNano() / 1_000_000 + " seconds");
// Create duration and add to instant
Duration twoHours = Duration.ofHours(2);
Instant future = start.plus(twoHours);
System.out.println("Two hours later: " + future);
}
}
此示例展示了如何使用 Instant 和 Duration 测量时间间隔。Duration.between 方法计算精确的时间差。Duration 也可以用于使用 Instants 执行时间算术。
来源
在本文中,我们介绍了 Java Instant 类的基本方法和特性。理解这些概念对于在现代 Java 应用程序中进行精确的时间处理至关重要。
作者
列出所有Java教程。