Java8中日期java.tim的API还不用?(媲美Joda-Time类库!)


一、概述

Java原本的java.util.Date和java.util.Calendar类会有老版本计算困难、线程不安全、无使用规范等缺点。JDK1.8推出新的时间处理类,解决了JDK1.7及之前的一些问题。

java.time包参考Joda-time的代码,功能强大,Joda-time能实现的功能,java.time也能实现。

参看:

  • https://www.bilibili.com/video/BV1aZ4y1j78G
  • https://www.runoob.com/java/java8-datetime-api.html

在学习java.time包下的新的时间处理类的时,第一步肯定是参看他的API

所有类:

在这里插入图片描述

枚举和异常:

在这里插入图片描述

看到枚举,大概就知道枚举是怎么用的了把~


二、常用类

  • Instant:时间轴上的时间戳。多用于类型转换
  • Duration:表示秒或者纳秒,适合处理很短的时间间隔,精度高
  • period:一段时间的年月日,比如距保险到期还有3年2月22天。
  • LocalDate:不可变的日期时间对象,可表示年月日。
  • LocalTime:不可变,可表示时分秒
  • LocalDateTime:不可变,可表示年月日时分秒

下面就是以LocalDateTime为例,做出一些简单的介绍和使用。

1.LocalDateTime

LocalDateTime由final修饰,不可变类,可表示年月日时分秒。这里以LocalDateTime为例,它的很多的方法,在其他类中使用方法都差不多。

1.1 now()方法

获取实例对象,表示当前时间节点,此方法是获取到电脑本机的时间节点。常用类被final修饰,不能使用new关键字创建实例对象,就提供了此方法获取到实例对象。

// 示例 创建LocalDateTime实例对象
LocalDateTime localDateTime = LocalDateTime.now();

1.2 of()方法

根据给定的参数生成对应的日期/时间对象,可以根据给定的参数生成对应的数据。

// 使用of方法 生成2021-05-01 01:01:01 (LocalDateTime)
LocalDateTime time = LocalDateTime.of(2021,Month.MAY,1,1,1,1);

可以选择传递到年月日时分秒,看给定的参数而定。如果of()方法里面的最后传递的参数是0,默认不封装。

当使用LocalDateTime的of()封装对象的时候,可以传递LocalDate和LocalTime两个参数,也会封装为LocalDateTime对象

1.3 plus增加

可增减年月日时分秒等,具体查看API。下列给出一点使用示例:

// 使用of方法 生成2021-05-01 01:01:01 (LocalDateTime)
LocalDateTime localDateTime = LocalDateTime.of(2021,Month.MAY,1,1,1,1);

// plus 1年1月1日,接收新的对象
LocalDateTime plus = localDateTime.plus(Period.of(1, 1, 1));
System.out.println(plus);

之后的plusDays(long days)就是增加天,plusHours(long hour)是增加小时,等等。

1.4 minus减少

和plus方法使用方式一样。

// 使用of方法 生成2021-05-01 01:01:01 (LocalDateTime)
LocalDateTime localDateTime = LocalDateTime.of(2021,Month.MAY,1,1,1,1);

// minus 1年1月1日,接收新的对象
LocalDateTime minus = localDateTime.minus(Period.of(1, 1, 1));
System.out.println(minus);

1.5 with修改

with可实现 修改日期中的某一个值,比如修改年、月、日等信息(注意,这里不是修改已经存在的类对象,而是创建一个新的类对象

// 使用of方法 生成2021-05-01 01:01:01 (LocalDateTime)
LocalDateTime localDateTime = LocalDateTime.of(2021,Month.MAY,1,1,1,1);

// with 修改小时为 2
LocalDateTime with = localDateTime.with(ChronoField.HOUR_OF_DAY, 2);
System.out.println(with);

with()配合TemporalAdjusters使用,可实现一些高级的操作,比如:

TemporalAdjusters是一个接口,传递进入with()的是一个TemporalAdjusters的实习类对象。

// 使用of方法 生成2021-05-01 01:01:01 (LocalDateTime)
LocalDateTime localDateTime = LocalDateTime.of(2021,Month.MAY,1,1,1,1);

// with 使用TemporalAdjusters修改为一年的最后一天
LocalDateTime with = localDateTime.with(TemporalAdjusters.lastDayOfYear());
System.out.println(with);

这是with()的用法,当然还有withMonth()等方法。


2.ZoneId和ZonedDateTime

ZoneId是时区集合,可以获取到时区的信息,ZonedDateTime是带有时区的LocalDateTime。

// 获取到ZoneId中的时区集合,Jdk收集了600个时区
Set<String> availableZoneIds = ZoneId.getAvailableZoneIds();
availableZoneIds.stream().forEach(System.out::println);

// 获取到带有时区的ZonedDateTime
ZonedDateTime zonedDateTime = ZonedDateTime.of(LocalDateTime.of(2021,Month.JULY,1,1,1,1),ZoneId.of("Asia/Shanghai"));
System.out.println(zonedDateTime);

两者配合使用,用于处理时区的相关信息。

设置时区,获取到其他时区的时间

// 构建LocalDateTime对象
LocalDateTime localDate = LocalDateTime.of(2021,Month.APRIL,1,1,1,1);

// 添加时区信息
ZonedDateTime Shanghai = localDate.atZone(ZoneId.of("Asia/Shanghai"));
System.out.println(Shanghai);

// 获取其他时区的时间
ZonedDateTime Tokyo = Shanghai.withZoneSameInstant(ZoneId.of("Asia/Tokyo"));
System.out.println(Tokyo);

输出:

2021-04-01T01:01:01+08:00[Asia/Shanghai]
2021-04-01T02:01:01+09:00[Asia/Tokyo]


三、实例超实用

不明白的即使查看官方API哦!

1.java.util.Date和java.time.LocalDateTime的转换

java.util.Date 》java.time.LocalDateTime

借助java.util.Date的toInstant()方法

// 1.初始化Date对象
Date date = new Date();

// 2.获取date的instant对象
Instant instant = date.toInstant();

// 3.填充时区 获取ZonedDateTime对象
ZonedDateTime zonedDateTime = instant.atZone(ZoneId.systemDefault());

// 4.将ZonedDateTime对象转化为LocalDateTime对象
LocalDateTime localDateTime = zonedDateTime.toLocalDateTime();
System.out.println(localDateTime);

java.time.LocalDateTime 》 java.util.Date

// 在上面的代码的基础之上,将LocalDateTime对象转化为java.util.Date
Date date = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
System.out.println(date);

2.java.sql.Date和java.sql.TimeStamp的转化

它们两个内部都提供了直接转化为java.time.LocalDateTime的方法。

两者分别转化为java.time.LocalDate和java.time.LocalDateTime

// java.sql.Date 转化为 java.time.LocalDate
Date date = new Date(System.currentTimeMillis());
LocalDate localDate = date.toLocalDate();
System.out.println(localDate);

// java.sql.Timestamp 转化为 java.time.LocalDateTime
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
LocalDateTime localDateTime = timestamp.toLocalDateTime();
System.out.println(localDateTime);

3.java.util.Calendar转化为ZonedDateTime

需要先获取时区,再获取到calendar的instant数据,之后操作看代码:

Calendar cal = Calendar.getInstance();

// 获取时区 TimeZone
TimeZone timeZone = cal.getTimeZone();

ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(cal.toInstant(), timeZone.toZoneId());

System.out.println(cal);
System.out.println(zonedDateTime);

4.LocalDateTime与String互相转换

使用DateTimeFormatter类提供静态常量,直接转化为指定的时间格式

/**
         * LocalDateTime 和 String 互相转换
         * DateTimeFormatter 代替 SimpleDateFormat
         */
LocalDateTime now = LocalDateTime.now();
// LocalDateTime -> String
String ISO_DATE_TIME = now.format(DateTimeFormatter.ISO_DATE_TIME);
System.out.println("ISO_DATE_TIME:"+ISO_DATE_TIME);

// String -> LocalDateTime
LocalDateTime parse = LocalDateTime.parse(ISO_DATE_TIME);
System.out.println(parse);

上面是通过DateTimeFormatter所提供的格式,把LocalDateTime转换为String。

下面提供自定义格式的String字符串进行显示:

LocalDateTime now =  LocalDateTime.now();
// 自定义格式进行显示
String format1 = now.format(DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss:SSS"));
System.out.println(format1);

String format2 = now.format(DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm"));
System.out.println(format2);

5.时间戳转化为指定时间格式的String

可通过java.time.Instant类转换,也可通过java.sql.Timestamp类转换

// 1.获取当前时间戳
Long time = System.currentTimeMillis();

// 2.1 通过Instant类获取到LocalDateTime类,在转化为指定格式的String
String format1 = LocalDateTime.ofInstant(Instant.ofEpochMilli(time), ZoneId.systemDefault()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
System.out.println(format1);

// 2.2 通过Timestamp类和DateTimeFormatter指定格式
String format2 = new Timestamp(time).toLocalDateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
System.out.println(format2);

这里值得注意的一点是:传递的Long类型的时间戳不能为null,这里的时间转换需要我们处理null的问题,而joda-time的时间转换,如果当前传递的Long类型时间戳为空,那么会自动返回当前pc的时间!(可以通过断点测试查看情况!)

多多益善~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值