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教程。