共计 1248 个字符,预计需要花费 4 分钟才能阅读完成。
我们已经讲过,计算机存储的当前时间,本质上只是一个不断递增的整数。Java 提供的 System.currentTimeMillis()
返回的就是以毫秒表示的当前时间戳。
这个当前时间戳在 java.time
中以 Instant
类型表示,我们用 Instant.now()
获取当前时间戳,效果和 System.currentTimeMillis()
类似:
import java.time.*; | |
public class Main {public static void main(String[] args) {Instant now = Instant.now(); | |
System.out.println(now.getEpochSecond()); // 秒 | |
System.out.println(now.toEpochMilli()); // 毫秒 | |
} | |
} |
打印的结果类似:
1568568760 | |
1568568760316 |
实际上,Instant
内部只有两个核心字段:
public final class Instant implements ... {private final long seconds; | |
private final int nanos; | |
} |
一个是以秒为单位的时间戳,一个是更精确的纳秒精度。它和 System.currentTimeMillis()
返回的 long
相比,只是多了更高精度的纳秒。
既然 Instant
就是时间戳,那么,给它附加上一个时区,就可以创建出ZonedDateTime
:
// 以指定时间戳创建 Instant: | |
Instant ins = Instant.ofEpochSecond(1568568760); | |
ZonedDateTime zdt = ins.atZone(ZoneId.systemDefault()); | |
System.out.println(zdt); // 2019-09-16T01:32:40+08:00[Asia/Shanghai] |
可见,对于某一个时间戳,给它关联上指定的ZoneId
,就得到了ZonedDateTime
,继而可以获得了对应时区的LocalDateTime
。
所以,LocalDateTime
,ZoneId
,Instant
,ZonedDateTime
和 long
都可以互相转换:
┌─────────────┐ | |
│LocalDateTime│────┐ | |
└─────────────┘ │ ┌─────────────┐ | |
├───▶│ZonedDateTime│ | |
┌─────────────┐ │ └─────────────┘ | |
│ ZoneId │────┘ ▲ | |
└─────────────┘ ┌─────────┴─────────┐ | |
│ │ | |
▼ ▼ | |
┌─────────────┐ ┌─────────────┐ | |
│ Instant │<───>│ long │ | |
└─────────────┘ └─────────────┘ |
转换的时候,只需要留意 long
类型以毫秒还是秒为单位即可。
小结
Instant
表示高精度时间戳,它可以和 ZonedDateTime
以及 long
互相转换。
正文完
星哥玩云-微信公众号
