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());
Instant 类的注意事项
时区问题:Instant 不包含时区信息,它总是表示 UTC 时间。如果需要显示特定时区的时间,需要转换为 ZonedDateTime。
精度问题:Instant 的精度取决于操作系统和硬件,大多数系统只能提供毫秒级别的精度。
不可变性:Instant 类是不可变的,所有修改操作都会返回新的 Instant 对象。
比较操作:比较两个 Instant 时,应该使用 isBefore() 和 isAfter() 方法,而不是直接比较时间戳。
序列化:Instant 类实现了 Serializable 接口,可以安全地进行序列化和反序列化。
点我分享笔记