Java时间戳类Instant的使用详解

 更新时间:2022年09月29日 10:32:27   作者:Java面试365  
这篇文章主要为大家详细介绍了Java中时间戳类Instant的使用方法,文中的示例代码讲解详细,对我们学习Java有一定帮助,需要的可以参考一下

前言

在JAVA8之前的版本,去获取时间戳(毫秒级别)常用的办法有两种

// 方法一:构建日期Date类然后调用getTime方法
Date date = new Date();
System.out.println(date.getTime());

// 方法二:使用System类静态方法获取
System.out.println(System.currentTimeMillis());

由于Date类大部分方法已经废弃,而且上面两种方法的时间戳只能精确到毫秒级别,所以我们有必要了解下jdk1.8推出的Instant类,该类可以将时间戳精确到纳秒级别。

Instant类

时间点

该类对象表示的是时间线上的一点,这个时间点存在标准的UTC时间,注意这个时间并不是指北京时间或东京时间而是指世界时间

// 获取当前时间 2022-09-26T03:12:58.517Z(比当地时间相差8个小时)
System.out.println(Instant.now());

// 获取系统默认时间戳 2022-09-26T11:12:58.517+08:00[Asia/Shanghai]
System.out.println(Instant.now().atZone(ZoneId.systemDefault()));

在Instant时间线上存在三个重要的点位,最大点、最小点、原点也就是说小于1970-01-01的时间戳就为负数,超过1970-01-01的时间戳就为正数

// 时间线上最大点  +1000000000-12-31T23:59:59.999999999Z
System.out.println(Instant.MAX);

// 时间线上最小点  -1000000000-01-01T00:00:00Z
System.out.println(Instant.MIN);

// 时间线上原点   1970-01-01T00:00:00Z
System.out.println(Instant.EPOCH);

// 输出结果为-8369623
System.out.println(Instant.parse("1969-09-26T03:06:17.323Z").getEpochSecond());

时间表示

在Instant中采用两个字段表示时间戳

/**
 * The number of seconds from the epoch of 1970-01-01T00:00:00Z.
 * 该字段表示Instant时间距离原点1970-01-01T00:00:00Z的时间(单位秒)
 */
private final long seconds;
/**
 * The number of nanoseconds, later along the time-line, from the seconds field.
 * This is always positive, and never exceeds 999,999,999.
 * 该字段表示Instant当前时间的纳秒数这个值不会超过999,999,999,因为1秒=1000_000_000纳秒
 */
private final int nanos;

Instant实例化

普通实例化分为如下几种

// 获取当前时间
Instant instant1 = Instant.now();

// 字符串转Instant
Instant instant2 = Instant.parse("2022-09-26T03:46:24.373Z");

// 构建秒级Instant对象,从时间1970-01-01T00:00:00Z开始计算(距离原点5000秒)
// 结果为:1970-01-01T01:23:20Z
Instant instant3 = Instant.ofEpochSecond(5000);

// 构建毫秒级Instant对象,同样从时间1970-01-01T00:00:00Z开始计算(距离原点5000毫秒)
// 结果为:1970-01-01T00:00:05Z
Instant instant4 = Instant.ofEpochMilli(5000);

还有一种特殊的如下,可以构建纳秒级的Instant对象

// 构建纳秒级Instant对象,同样从时间1970-01-01T00:00:00Z开始计算
// 参数:epochSecond(秒),nanoAdjustment(纳秒)
// 结果为:1970-01-01T00:00:05.000001111Z
Instant instant5 = Instant.ofEpochSecond(5, 1111);

不过我们需要注意Instant.ofEpochSecond方法的源码,如下

static final long NANOS_PER_SECOND = 1000_000_000L;
/**
 * @param epochSecond  秒从1970-01-01T00:00:00Z开始计算
 * @param nanoAdjustment  纳秒
 */
public static Instant ofEpochSecond(long epochSecond, long nanoAdjustment) {
    // Math.floorDiv是除法运算,返回小于或等于商的整数 Math.floorDiv(25, 3)=8
    // Math.addExact加法运算,Math.addExact(1, 2)=3
    long secs = Math.addExact(epochSecond, Math.floorDiv(nanoAdjustment, NANOS_PER_SECOND));
    // Math.floorMod是模运算,Math.floorMod(9, 20)=9
    int nos = (int)Math.floorMod(nanoAdjustment, NANOS_PER_SECOND);
    return create(secs, nos);
}

Instant获取参数

Instant instant = Instant.now();
// 时区相差8小时 2022-09-26T07:04:19.110Z
System.out.println(instant);

System.out.println("秒:"+instant.getEpochSecond());

System.out.println("毫秒:"+instant.toEpochMilli());
// 1毫秒 = 1000 000 纳秒
System.out.println("纳秒:"+instant.getNano());

Instant时间点比较

由于时间点位于时间线上,所以可以直接进行对比。

Instant instant1 = Instant.parse("2022-09-26T07:04:19.110Z");
Instant instant2 = Instant.parse("2022-09-26T07:04:19.110Z");
Instant instant3 = Instant.parse("2022-08-26T07:04:19.110Z");

// 相等为0
System.out.println(instant1.compareTo(instant2));
// instant1大于instant3 为1
System.out.println(instant1.compareTo(instant3));
// instant1小于instant3 为-1
System.out.println(instant3.compareTo(instant1));

// true
System.out.println(instant1.isAfter(instant3));
// false
System.out.println(instant1.isBefore(instant3));

Instant时间点运算

Instant instant1 = Instant.parse("2022-09-26T07:04:19.110Z");

// 在instant1的基础上增加2秒,值为:2022-09-26T07:04:21.110Z
System.out.println(instant1.plusSeconds(2));

// 在instant1的基础上增加1毫秒,值为:2022-09-26T07:04:19.111Z
System.out.println(instant1.plusMillis(1));

// 在instant1的基础上增加1001纳秒,值为:2022-09-26T07:04:19.110001001Z
System.out.println(instant1.plusNanos(1001));

// 在instant1的基础上增加1秒,值为:2022-09-26T07:04:20.110Z
// 该值取决于后面指定的单位,可以从ChronoUnit枚举类获取
System.out.println(instant1.plus(1, ChronoUnit.SECONDS));

// 在instant1的基础上减去1秒,值为:2022-09-26T07:04:18.110Z
// plus是增加,minus是减少,逻辑类似可以参考上面plus相关A
System.out.println(instant1.minusSeconds(1));

Instant时间点计算时需要注意,无论是调用plus或者minus相关API都会重新创建新对象。

到此这篇关于Java时间戳类Instant的使用详解的文章就介绍到这了,更多相关Java时间戳类Instant内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java设计模式理解依赖于抽象不依赖具体的分析

    java设计模式理解依赖于抽象不依赖具体的分析

    这篇文章主要为大家介绍了java设计模式的规则,理解依赖于抽象不依赖具体的示例分析,有需要的朋友可以借鉴参考下,希望能够有所帮助
    2021-10-10
  • 解决IDEA新建xml文件显示为普通的text文本问题

    解决IDEA新建xml文件显示为普通的text文本问题

    IntelliJ IDEA新建XML文件时显示为普通文本,可以通过以下步骤解决:1.检查项目文件过滤器,确保没有隐藏XML文件类型;2.在XML文件中添加或修改文件类型关联;3.如果问题依然存在,检查并删除自定义的文件类型过滤器
    2024-11-11
  • Kotlin基础教程之dataclass,objectclass,use函数,类扩展,socket

    Kotlin基础教程之dataclass,objectclass,use函数,类扩展,socket

    这篇文章主要介绍了Kotlin基础教程之dataclass,objectclass,use函数,类扩展,socket的相关资料,需要的朋友可以参考下
    2017-05-05
  • java使用任务架构执行任务调度示例

    java使用任务架构执行任务调度示例

    在Java 5.0之前启动一个任务是通过调用Thread类的start()方法来实现的,5.0里提供了一个新的任务执行架构使你可以轻松地调度和控制任务的执行,并且可以建立一个类似数据库连接池的线程池来执行任务,下面看一个示例
    2014-01-01
  • Java实现LeetCode(报数)

    Java实现LeetCode(报数)

    这篇文章主要介绍了Java实现LeetCode(报数),本文通过使用java实现leetcode的报数题目和实现思路分析,需要的朋友可以参考下
    2021-06-06
  • Java如何在不存在文件夹的目录下创建文件

    Java如何在不存在文件夹的目录下创建文件

    这篇文章主要介绍了Java如何在不存在文件夹的目录下创建文件,代码简单易懂,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2017-08-08
  • Spring Boot 配置 Hikari 数据库连接池的操作代码

    Spring Boot 配置 Hikari 数据库连接池的操作代码

    数据库连接池是一个提高程序与数据库的连接的优化,连接池它主要作用是提高性能、节省资源、控制连接数、连接管理等操作,这篇文章主要介绍了SpringBoot配置Hikari数据库连接池,需要的朋友可以参考下
    2023-09-09
  • Java中JWT(JSON Web Token)的运用具体案例

    Java中JWT(JSON Web Token)的运用具体案例

    这篇文章主要介绍了Java中JWT(JSON Web Token)的运用具体案例,JWT(JSON Web Token)是一种开放标准,用于在网络应用环境中安全地传递信息,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-11-11
  • Java并发编程:volatile关键字详细解析

    Java并发编程:volatile关键字详细解析

    这篇文章主要介绍了Java并发编程:volatile关键字详细解析,对学习volatile关键字有一定的认识,有需要的可以了解一下。
    2016-11-11
  • IDEA 设置显示内存的使用情况和内存回收的方法

    IDEA 设置显示内存的使用情况和内存回收的方法

    这篇文章主要介绍了IDEA 设置显示内存的使用情况和内存回收的方法,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-04-04

最新评论