Java日期时间API系列31-----Jdk8中java.time包中的新的日期时间API类,时间戳的获取方式对比、转换和使用。
时间戳是指格林威治时间1970年01月01日00时00分00秒起至现在的总毫秒数,是所有时间的基础,其他时间可以通过时间戳转换得到。Java中本来已经有相关获取时间戳的方法,Java8后增加新的类Instant等专用于处理时间戳问题。
1 获取时间戳的方法和性能对比
1.1 获取时间戳方法
Java8以前可以使用System.currentTimeMillis() 、new Date().getTime() 、和Calendar.getInstance().getTimeInMillis()获取。Java8以后可以另外通过Instant.now().toEpochMilli()和Clock.systemUTC().millis()获取。
比较简单,下面直接看代码:
/**
* 使用System获取时间戳
*/
@Test
public void getEpochMilliWithSystem(){
long s = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
System.currentTimeMillis();
}
System.out.println("getEpochMilliWithSystem cost:"+(System.currentTimeMillis()-s));
} /**
* 使用Date获取时间戳
*/
@Test
public void getEpochMilliWithDate(){
long s = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
new Date().getTime();
}
System.out.println("getEpochMilliWithDate cost:"+(System.currentTimeMillis()-s));
} /**
* 使用Calendar获取时间戳
*/
@Test
public void getEpochMilliWithCalendar(){
long s = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
Calendar.getInstance().getTimeInMillis();
}
System.out.println("getEpochMilliWithCalendar cost:"+(System.currentTimeMillis()-s));
} /**
* 使用Instant获取时间戳
*/
@Test
public void getEpochMilliWithInstant(){
long s = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
Instant.now().toEpochMilli();
}
System.out.println("getEpochMilliWithInstant cost:"+(System.currentTimeMillis()-s));
} /**
* 使用Clock获取时间戳
*/
@Test
public void getEpochMilliWithClock(){
long s = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
Clock.systemUTC().millis();
}
System.out.println("getEpochMilliWithClock cost:"+(System.currentTimeMillis()-s));
}
查看过上面相关源码,基本都是通过System.currentTimeMillis() 来创建对象的。比如 new Date:
public Date() {
this(System.currentTimeMillis());
}
1.2 性能对比
上面代码执行输出:
getEpochMilliWithSystem cost:5
getEpochMilliWithDate cost:38
getEpochMilliWithCalendar cost:1094
getEpochMilliWithInstant cost:106
getEpochMilliWithClock cost:17
通过1.1 中的分析得知基本都是通过System.currentTimeMillis() 来创建对象的System.currentTimeMillis()最快,性能最好。
所以,性能排序:System > Clock > Date > Instant > Calendar 。
2.时间戳转换为其他类
2.1 时间戳和其他类型的转换
/**
* 时间戳epochMilli毫秒转Date
* @param epochMilli
* @return
*/
public static Date toDate(long epochMilli){
Objects.requireNonNull(epochMilli, "epochMilli");
return new Date(epochMilli);
}
/**
* 时间戳epochMilli毫秒转LocalDateTime
* @param epochMilli
* @return
*/
public static LocalDateTime toLocalDateTime(long epochMilli) {
Objects.requireNonNull(epochMilli, "epochMilli");
return LocalDateTime.ofInstant(Instant.ofEpochMilli(epochMilli), ZoneId.systemDefault());
}
/**
* 时间戳epochMilli毫秒转LocalDate
* @param epochMilli
* @return
*/
public static LocalDate toLocalDate(long epochMilli) {
Objects.requireNonNull(epochMilli, "epochMilli");
return toLocalDateTime(epochMilli).toLocalDate();
}
/**
* 时间戳epochMilli毫秒转Instant
* @param epochMilli
* @return
*/
public static Instant toInstant(long epochMilli) {
Objects.requireNonNull(epochMilli, "epochMilli");
return Instant.ofEpochMilli(epochMilli);
}
/**
* 时间戳epochMilli毫秒转ZonedDateTime,时区为系统默认时区
* @param epochMilli
* @return
*/
public static ZonedDateTime toZonedDateTime(long epochMilli) {
Objects.requireNonNull(epochMilli, "epochMilli");
return LocalDateTime.ofInstant(Instant.ofEpochMilli(epochMilli), ZoneId.systemDefault())
.atZone(ZoneId.systemDefault());
}
/**
* 时间戳epochMilli转Timestamp
* @param epochMilli
* @return
*/
public static Timestamp toTimestamp(long epochMilli){
return new Timestamp(epochMilli);
} /**
* Date转时间戳
* 从1970-01-01T00:00:00Z开始的毫秒值
* @param date
* @return
*/
public static long toEpochMilli(Date date){
Objects.requireNonNull(date, "date");
return date.getTime();
}
/**
* LocalDateTime转时间戳
* 从1970-01-01T00:00:00Z开始的毫秒值
* @param localDateTime
* @return
*/
public static long toEpochMilli(LocalDateTime localDateTime){
return toInstant(localDateTime).toEpochMilli();
}
/**
* LocalDate转时间戳
* 从1970-01-01T00:00:00Z开始的毫秒值
* @param localDate
* @return
*/
public static long toEpochMilli(LocalDate localDate){
return toInstant(localDate).toEpochMilli();
}
/**
* Instant转时间戳
* 从1970-01-01T00:00:00Z开始的毫秒值
* @param instant
* @return
*/
public static long toEpochMilli(Instant instant){
Objects.requireNonNull(instant, "instant");
return instant.toEpochMilli();
}
/**
* ZonedDateTime转时间戳,注意,zonedDateTime时区必须和当前系统时区一致,不然会出现问题
* 从1970-01-01T00:00:00Z开始的毫秒值
* @param zonedDateTime
* @return
*/
public static long toEpochMilli(ZonedDateTime zonedDateTime) {
Objects.requireNonNull(zonedDateTime, "zonedDateTime");
return zonedDateTime.toInstant().toEpochMilli();
}
/**
* Timestamp转时间戳
* 从1970-01-01T00:00:00Z开始的毫秒值
* @param timestamp
* @return
*/
public static long toEpochMilli(Timestamp timestamp){
Objects.requireNonNull(timestamp, "timestamp");
return timestamp.getTime();
}
测试代码:
/**
* 时间戳转换测试
*/
@Test
public void epochMilliConverterTest(){
System.out.println("===================epochMilliConverterTest=====================");
Date date = new Date();
long epochMilli = date.getTime();
System.out.println("epochMilli:"+epochMilli);
System.out.println("===================ToOther=====================");
System.out.println(DateTimeConverterUtil.toDate(epochMilli));
System.out.println(DateTimeConverterUtil.toLocalDateTime(epochMilli));
System.out.println(DateTimeConverterUtil.toLocalDate(epochMilli));
System.out.println(DateTimeConverterUtil.toInstant(epochMilli));
System.out.println(DateTimeConverterUtil.toZonedDateTime(epochMilli));
System.out.println(DateTimeConverterUtil.toTimestamp(epochMilli));
System.out.println("===================toEpochMilli=====================");
System.out.println(DateTimeConverterUtil.toEpochMilli(new Date()));
System.out.println(DateTimeConverterUtil.toEpochMilli(LocalDateTime.now()));
// 另一种方式: +8 时区
System.out.println(LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli());
System.out.println(DateTimeConverterUtil.toEpochMilli(LocalDate.now()));
System.out.println(DateTimeConverterUtil.toEpochMilli(Instant.now()));
System.out.println(DateTimeConverterUtil.toEpochMilli(ZonedDateTime.now()));
System.out.println(DateTimeConverterUtil.toEpochMilli(new Timestamp(System.currentTimeMillis())));
}
输出:
===================epochMilliConverterTest=====================
epochMilli:1587950768191
===================ToOther=====================
Mon Apr 27 09:26:08 CST 2020
2020-04-27T09:26:08.191
2020-04-27
2020-04-27T01:26:08.191Z
2020-04-27T09:26:08.191+08:00[Asia/Shanghai]
2020-04-27 09:26:08.191
===================toEpochMilli=====================
1587950768304
1587950768304
1587950768304
1587916800000
1587950768305
1587950768305
1587950768305
3 Timestamp
Timestamp是Java8以前处理时间戳的类。Timestamp和其他类型的转换
/**
* Timestamp转LocalDateTime
* @param timestamp
* @return
*/
public static LocalDateTime toLocalDateTime(Timestamp timestamp) {
Objects.requireNonNull(timestamp, "timestamp");
return timestamp.toLocalDateTime();
}
/**
* Timestamp转Instant
* @param timestamp
* @return
*/
public static Instant toInstant(Timestamp timestamp) {
Objects.requireNonNull(timestamp, "timestamp");
return timestamp.toInstant();
}
/**
* Timestamp转时间戳
* 从1970-01-01T00:00:00Z开始的毫秒值
* @param timestamp
* @return
*/
public static long toEpochMilli(Timestamp timestamp){
Objects.requireNonNull(timestamp, "timestamp");
return timestamp.getTime();
}
/**
* Date转Timestamp
* @param date
* @return
*/
public static Timestamp toTimestamp(Date date){
Objects.requireNonNull(date, "date");
return new Timestamp(date.getTime());
}
/**
* LocalDateTime转Timestamp
* @param localDateTime
* @return
*/
public static Timestamp toTimestamp(LocalDateTime localDateTime){
Objects.requireNonNull(localDateTime, "localDateTime");
return Timestamp.valueOf(localDateTime);
} /**
* Instant转Timestamp
* @param instant
* @return
*/
public static Timestamp toTimestamp(Instant instant){
Objects.requireNonNull(instant, "instant");
return Timestamp.from(instant);
} /**
* 时间戳epochMilli转Timestamp
* @param epochMilli
* @return
*/
public static Timestamp toTimestamp(long epochMilli){
return new Timestamp(epochMilli);
}
测试代码:
/**
* Timestamp转换测试
*/
@Test
public void timestampConverterTest(){
System.out.println("===================timestampConverterTest=====================");
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
long epochMilli = timestamp.getTime();
System.out.println("epochMilli:"+epochMilli);
System.out.println("===================ToOther=====================");
System.out.println(DateTimeConverterUtil.toLocalDateTime(timestamp));
System.out.println(DateTimeConverterUtil.toInstant(timestamp));
System.out.println(DateTimeConverterUtil.toEpochMilli(timestamp));
System.out.println("===================toEpochMilli=====================");
System.out.println(DateTimeConverterUtil.toTimestamp(new Date()));
System.out.println(DateTimeConverterUtil.toTimestamp(LocalDateTime.now()));
System.out.println(DateTimeConverterUtil.toTimestamp(Instant.now()));
System.out.println(DateTimeConverterUtil.toTimestamp(epochMilli));
}
输出:
===================timestampConverterTest=====================
epochMilli:1587950937677
===================ToOther=====================
2020-04-27T09:28:57.677
2020-04-27T01:28:57.677Z
1587950937677
===================toEpochMilli=====================
2020-04-27 09:28:57.774
2020-04-27 09:28:57.781
2020-04-27 09:28:57.782
2020-04-27 09:28:57.677
4 Instant
Java8可以使用Instant方便的获取时间戳相关的信息。
4.1 创建方式
public static Instant now() {
return Clock.systemUTC().instant();
}
Instant now方法默认使用的是UTC,协调世界时。now(Clock clock)方法 clock参数可以设置时区信息,就可以获取不同时区的Instant,比如 Clock systemDefaultZone()
或指定时区 Clock system(ZoneId zone)等。
4.2 获取时间戳
public long toEpochMilli() 获取时间戳 单位为毫秒。
public long getEpochSecond() 获取时间戳 单位为秒。
5.总结
通过上面可以看出,时间戳是所有时间创建和转换的基础,通过简单的System.currentTimeMillis()获取到,但时间戳只是一个简单的数字,不转换为其他时间类没有意义,比如 年、月、日、时、分、秒、星期、闰年、时区、夏令时等,更多相关的比如各种节假日,星座等附加意义的信息。
源代码地址:https://github.com/xkzhangsan/xk-time
Java日期时间API系列31-----Jdk8中java.time包中的新的日期时间API类,时间戳的获取方式对比、转换和使用。的更多相关文章
- API接口自动化之3 同一个war包中多个接口做自动化测试
同一个war包中多个接口做自动化测试 一个接口用一个测试类,每个测试用例如下,比如下面是4个测试用例,每个详细的测试用例中含有请求入参,返回体校验,以此来判断每条测试用例是否通过 一个war包中,若含 ...
- Andriod项目开发实战(1)——如何在Eclipse中的一个包下建新包
最开始是想将各个类分门别类地存放在不同的包中,所以想在项目源码包中新建几个不同功能的包eg:utils.model.receiver等,最后的结果应该是下图左边这样的: 很明显建立项目后的架构是上 ...
- JDK中的Atomic包中的类及使用
引言 Java从JDK1.5开始提供了java.util.concurrent.atomic包,方便程序员在多线程环境下,无锁的进行原子操作.原子变量的底层使用了处理器提供的原子指令,但是不同的CPU ...
- Mac 如何导出ipa文件中Assets.car包中的切图
在之前 获取 AppStore 中 应用 的 IPA 包文件(Mac OS 13+)中获取到应用的 IPA 包,可以取出应用的部分图片(如 Logo),如果项目工程中把图片添加到 Assets.xca ...
- 【转】Eclipse中查看jar包中的源码
(简单的方式:通过jd-gui来进行反编译,最简单!,参考我的另一篇博文, 地址:http://www.cnblogs.com/gmq-sh/p/4277991.html) Java Decompil ...
- Package.json中dependencies依赖包中^符号和~符号前缀的区别
刚git了webpack的包发现package.json里面dependencies依赖包的版本号前面的符号有两种,一种是~,一种是^,如下图标记: 然后搜了下在stackoverflow上找到一个比 ...
- Java8系列 (六) 新的日期和时间API
概述 在Java8之前, 我们一般都是使用 SimpleDateFormat 来解析和格式化日期时间, 但它是线程不安全的. @Test public void test() { SimpleDate ...
- Java8 新的日期和时间API(笔记)
LocalDate LocalTime Instant duration以及Period 使用LocalDate和LocalTime //2017-03-20 LocalDate date = Loc ...
- Redis总结(五)缓存雪崩和缓存穿透等问题 Web API系列(三)统一异常处理 C#总结(一)AutoResetEvent的使用介绍(用AutoResetEvent实现同步) C#总结(二)事件Event 介绍总结 C#总结(三)DataGridView增加全选列 Web API系列(二)接口安全和参数校验 RabbitMQ学习系列(六): RabbitMQ 高可用集群
Redis总结(五)缓存雪崩和缓存穿透等问题 前面讲过一些redis 缓存的使用和数据持久化.感兴趣的朋友可以看看之前的文章,http://www.cnblogs.com/zhangweizhon ...
- Web API系列(三)统一异常处理
前面讲了webapi的安全验证和参数安全,不清楚的朋友,可以看看前面的文章,<Web API系列(二)接口安全和参数校验>,本文主要介绍Web API异常结果的处理.作为内部或者是对外提供 ...
随机推荐
- M1 Mac安装anaconda3
1.正常安装 首先进入官网https://www.anaconda.com/ 下载,安装 自行大胆的安装 2.环境配置 直接安装完成后,代码文件的存储路径为默认路径,为了更好的管理代码文件我们需要更换 ...
- 使用Java对稀疏数组的压缩与还原
稀疏矩阵的压缩与还原 稀疏数组中元素个数很少或者有大量的重复值,如果直接保存保存,会浪费很多空间,这时,就可以考虑对数组进行压缩存储. 先定义一个稀疏数组 //创建一个二维数组 11 * 11 int ...
- 【Mybatis-Plus】使用QueryWrapper作为自定义SQL的条件参数
发现同事的自定义SQL写法是这样的 连表之后使用的条件是 ${ew.customSqlSegment} @Param声明的常量: /** * wrapper 类 */ String WRAPPER = ...
- 【C】Re07 二级指针,指针与参数
一.二级指针: 变量 = 内存地址 + 存储值: 指针 = 内存地址 + 变量内存地址: 二级指针 = 内存地址 + 指针内存地址: 多级指针 = 内存地址 + 上一级内存地址: void moreP ...
- nvidia显卡的售后真的是不敢要人恭维——拆机箱时误拧显卡自身挡板螺丝被拒保
事情比较简单,单位在nvidia的经销商那里购买的nvidia titan rtx显卡,保修期内坏掉,拆下来的过程中误拧了挡板的螺丝,结果被拒保,这里就是单纯的记录这件事情. 这件事确实我这方面有不对 ...
- java多线程之-CAS无锁-常见API
1.背景 这一节,就是学习常用的cas对象与api ..... 2.原子整数 直接看代码吧,或者看API文档 2.1.AtomicInteger的API演示 package com.ldp.demo0 ...
- Apache DolphinScheduler社区又一PMC获推选通过!
PROFILE 姓名:程鑫 公司:阿里云 职位:开发工程师 Github ID: rickchengx 从事领域:大数据调度系统开发 兴趣爱好:健身 推举理由 他于2022年8月2日开始了他的Dolp ...
- 使用一次sql请求,返回分页数据和总条数
日常搬砖,总少不了需要获取分页数据和总行数. 一直以来的实践是编码两次sql请求,分别拉分页数据和totolCount. 最近我在思考: 常规实践为什么不是 在一次sql请求中中执行多次sql查询或多 ...
- jdk8的Steam流工作常用方法总结
Steam流工作常用方法总结 收集list 以某几个字段为键以内容为list的map Map<String, List<TVoucherDetail>> tVoucherDet ...
- .net core下使用事件总线
随着微服务的火热,DDD(领域驱动设计模式)思想风起云涌,冲击着整个软件生态系统.其中,事件总线那是必须知道的了,于是我便抱着一个学习DDD的心态搭建了一个博客网站,目前该网站正在建设 ...