Java Instant 类
Instant 类是 Java 8 引入的日期时间 API (java.time 包)中的一个重要类,它代表时间线上的一个瞬时点。这个类主要用于记录时间戳,精确到纳秒级别。
Instant 类有以下主要特点:
- 表示从 1970-01-01T00:00:00Z (即 Unix 纪元)开始的时间
- 不包含时区信息
- 是不可变且线程安全的
- 精确到纳秒(而传统的 Date 类只精确到毫秒)
Instant 类的创建
获取当前时刻
实例
Instant now = Instant.now(); // 获取当前时刻
从纪元时间创建
实例
Instant instant1 = Instant.ofEpochSecond(3); // 1970-01-01T00:00:03Z
Instant instant2 = Instant.ofEpochSecond(3, 0); // 同上
Instant instant3 = Instant.ofEpochSecond(2, 1_000_000_000); // 3秒后的1纳秒
Instant instant4 = Instant.ofEpochSecond(4, -1_000_000_000); // 3秒前的1纳秒
Instant instant2 = Instant.ofEpochSecond(3, 0); // 同上
Instant instant3 = Instant.ofEpochSecond(2, 1_000_000_000); // 3秒后的1纳秒
Instant instant4 = Instant.ofEpochSecond(4, -1_000_000_000); // 3秒前的1纳秒
从毫秒创建
实例
Instant instant = Instant.ofEpochMilli(1000); // 1970-01-01T00:00:01Z
Instant 类的常用方法
获取时间信息
实例
Instant instant = Instant.now();
long seconds = instant.getEpochSecond(); // 获取从1970-01-01开始的秒数
int nanos = instant.getNano(); // 获取纳秒部分
long seconds = instant.getEpochSecond(); // 获取从1970-01-01开始的秒数
int nanos = instant.getNano(); // 获取纳秒部分
时间比较
实例
Instant instant1 = Instant.now();
Instant instant2 = instant1.plusSeconds(10);
boolean isBefore = instant1.isBefore(instant2); // true
boolean isAfter = instant1.isAfter(instant2); // false
Instant instant2 = instant1.plusSeconds(10);
boolean isBefore = instant1.isBefore(instant2); // true
boolean isAfter = instant1.isAfter(instant2); // false
时间运算
实例
Instant instant = Instant.now();
// 加10秒
Instant later = instant.plusSeconds(10);
// 减5分钟
Instant earlier = instant.minus(Duration.ofMinutes(5));
// 加2天4小时30分钟
Instant future = instant.plus(2, ChronoUnit.DAYS)
.plus(4, ChronoUnit.HOURS)
.plus(30, ChronoUnit.MINUTES);
// 加10秒
Instant later = instant.plusSeconds(10);
// 减5分钟
Instant earlier = instant.minus(Duration.ofMinutes(5));
// 加2天4小时30分钟
Instant future = instant.plus(2, ChronoUnit.DAYS)
.plus(4, ChronoUnit.HOURS)
.plus(30, ChronoUnit.MINUTES);
Instant 与其他日期时间类的转换
Instant 与 LocalDateTime
实例
Instant instant = Instant.now();
// Instant 转 LocalDateTime
LocalDateTime ldt = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
// LocalDateTime 转 Instant
Instant fromLdt = ldt.toInstant(ZoneOffset.UTC);
// Instant 转 LocalDateTime
LocalDateTime ldt = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
// LocalDateTime 转 Instant
Instant fromLdt = ldt.toInstant(ZoneOffset.UTC);
Instant 与 ZonedDateTime
实例
Instant instant = Instant.now();
// Instant 转 ZonedDateTime
ZonedDateTime zdt = instant.atZone(ZoneId.of("Asia/Shanghai"));
// ZonedDateTime 转 Instant
Instant fromZdt = zdt.toInstant();
// Instant 转 ZonedDateTime
ZonedDateTime zdt = instant.atZone(ZoneId.of("Asia/Shanghai"));
// ZonedDateTime 转 Instant
Instant fromZdt = zdt.toInstant();
Instant 与 Date
实例
// Instant 转 Date
Date date = Date.from(instant);
// Date 转 Instant
Instant fromDate = date.toInstant();
Date date = Date.from(instant);
// Date 转 Instant
Instant fromDate = date.toInstant();
Instant 类的实际应用
记录事件时间戳
实例
public class Event {
private String name;
private Instant timestamp;
public Event(String name) {
this.name = name;
this.timestamp = Instant.now();
}
// getters...
}
private String name;
private Instant timestamp;
public Event(String name) {
this.name = name;
this.timestamp = Instant.now();
}
// getters...
}
计算时间间隔
实例
Instant start = Instant.now();
// 执行一些操作...
Instant end = Instant.now();
Duration duration = Duration.between(start, end);
System.out.println("操作耗时: " + duration.toMillis() + "毫秒");
// 执行一些操作...
Instant end = Instant.now();
Duration duration = Duration.between(start, end);
System.out.println("操作耗时: " + duration.toMillis() + "毫秒");
定时任务
实例
Instant now = Instant.now();
Instant nextRun = now.plus(1, ChronoUnit.HOURS);
while (Instant.now().isBefore(nextRun)) {
// 等待到指定时间
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 执行定时任务
System.out.println("定时任务执行时间: " + Instant.now());
Instant nextRun = now.plus(1, ChronoUnit.HOURS);
while (Instant.now().isBefore(nextRun)) {
// 等待到指定时间
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 执行定时任务
System.out.println("定时任务执行时间: " + Instant.now());
综合实例
实例
import java.time.Instant;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
public class InstantExample {
public static void main(String[] args) {
// 1. 获取当前时刻的 Instant
Instant now = Instant.now();
System.out.println("当前时刻: " + now);
// 2. 从字符串解析 Instant
Instant parsedInstant = Instant.parse("2023-05-15T10:15:30.00Z");
System.out.println("解析的 Instant: " + parsedInstant);
// 3. 创建特定时刻的 Instant
Instant epochInstant = Instant.ofEpochSecond(0);
System.out.println("纪元时间 (1970-01-01T00:00:00Z): " + epochInstant);
Instant specificInstant = Instant.ofEpochSecond(1684131330);
System.out.println("特定时间戳: " + specificInstant);
// 4. 时间运算
Instant later = now.plusSeconds(60); // 加60秒
System.out.println("60秒后: " + later);
Instant earlier = now.minus(2, ChronoUnit.HOURS); // 减2小时
System.out.println("2小时前: " + earlier);
// 5. 计算时间间隔
Duration duration = Duration.between(earlier, later);
System.out.println("时间间隔: " + duration.toMinutes() + " 分钟");
// 6. 比较时间
System.out.println("earlier 是否在 later 之前: " + earlier.isBefore(later));
System.out.println("later 是否在 earlier 之后: " + later.isAfter(earlier));
// 7. 获取时间戳
System.out.println("从纪元开始的秒数: " + now.getEpochSecond());
System.out.println("纳秒部分: " + now.getNano());
}
}
import java.time.Duration;
import java.time.temporal.ChronoUnit;
public class InstantExample {
public static void main(String[] args) {
// 1. 获取当前时刻的 Instant
Instant now = Instant.now();
System.out.println("当前时刻: " + now);
// 2. 从字符串解析 Instant
Instant parsedInstant = Instant.parse("2023-05-15T10:15:30.00Z");
System.out.println("解析的 Instant: " + parsedInstant);
// 3. 创建特定时刻的 Instant
Instant epochInstant = Instant.ofEpochSecond(0);
System.out.println("纪元时间 (1970-01-01T00:00:00Z): " + epochInstant);
Instant specificInstant = Instant.ofEpochSecond(1684131330);
System.out.println("特定时间戳: " + specificInstant);
// 4. 时间运算
Instant later = now.plusSeconds(60); // 加60秒
System.out.println("60秒后: " + later);
Instant earlier = now.minus(2, ChronoUnit.HOURS); // 减2小时
System.out.println("2小时前: " + earlier);
// 5. 计算时间间隔
Duration duration = Duration.between(earlier, later);
System.out.println("时间间隔: " + duration.toMinutes() + " 分钟");
// 6. 比较时间
System.out.println("earlier 是否在 later 之前: " + earlier.isBefore(later));
System.out.println("later 是否在 earlier 之后: " + later.isAfter(earlier));
// 7. 获取时间戳
System.out.println("从纪元开始的秒数: " + now.getEpochSecond());
System.out.println("纳秒部分: " + now.getNano());
}
}
输出结果类似如下:
当前时刻: 2025-05-01T03:19:09.345806Z 解析的 Instant: 2023-05-15T10:15:30Z 纪元时间 (1970-01-01T00:00:00Z): 1970-01-01T00:00:00Z 特定时间戳: 2023-05-15T06:15:30Z 60秒后: 2025-05-01T03:20:09.345806Z 2小时前: 2025-05-01T01:19:09.345806Z 时间间隔: 121 分钟 earlier 是否在 later 之前: true later 是否在 earlier 之后: true 从纪元开始的秒数: 1746069549 纳秒部分: 345806000
Instant 类的注意事项
时区问题:Instant 不包含时区信息,它总是表示 UTC 时间。如果需要显示特定时区的时间,需要转换为 ZonedDateTime。
精度问题:Instant 的精度取决于操作系统和硬件,大多数系统只能提供毫秒级别的精度。
不可变性:Instant 类是不可变的,所有修改操作都会返回新的 Instant 对象。
比较操作:比较两个 Instant 时,应该使用 isBefore() 和 isAfter() 方法,而不是直接比较时间戳。
序列化:Instant 类实现了 Serializable 接口,可以安全地进行序列化和反序列化。
点我分享笔记