简述
在编码业务中遇到时间和日期相关的开发任务时,JDK帮我们封装好了几个和时间日期相关的工具类给我们使用,一方面比较方便,不用我们自己封装了,另一方面是统一了规范。
JDK1.8之前
在JDK1.8之前,我们想进行时间、日期的表示的操作,使用的是这三个类
java.util.Date
java.util.Calendar
java.text.SimpleDateFormat
比较重要的是,这三个类都都不是线程安全的,而且还比较难用,所以这里不作介绍
JDK1.8开始
JDK1.8开始,时间和日期的工具类遵守ISO8601标准、命名更加准确、功能更加丰富、线程安全
1.8开始在time包下的类就是和时间和日期相关的类:
Instant、LocalDate、LocalTime、LocalDateTime、OffsetDateTime、ZonedDateTime、Duration、Period、DateTimeFormatter
首先先来看一张表示日期时间类的关系图
可以看到从LocalDate
到ZonedDateTime
,各个类能表示的范围是逐步递增的
Instant类
Instant类表示的是一个时间戳,是时间上的一个点。Instant精准到毫秒,Instant内部用两个long存数据,一部分是seconds
,表示从1970-01-01 00:00:00开始到现在的秒数,另一个部分是nanos
,表示纳秒部分。
使用Instant.now()
创建一个当前时间的时间戳实例
Instant instant = Instant.now();
System.out.println(instant);
结果为:
2022-03-11T03:14:15.501674200Z
使用toEpochMilli()
获取该时间戳到1970年1月1日00:00的毫秒数
我们可以用Instant
类计算程序运行的时间
Instant pre = Instant.now();
//你想统计运行时间的代码
Instant now = Instant.now();
System.out.println(now.toEpochMilli() - pre.toEpochMilli());
LocalDate类
LocalDate
是一个不可变的日期时间对象,表示日期,通常被视为年月日。
使用LocalDate.now()
创建一个今天的日期实例
LocalDate localDate = LocalDate.now();
System.out.println(localDate);
结果为:
2022-03-11
也可以使用of(int year, int month, int dayOfMonth)
从一年,一个月和一天获得一个 LocalDate
的实例。
LocalTime类
LocalTime
是一个不可变的日期时间对象,代表一个时间,通常被看作是小时 - 秒,精度为纳秒
用LocalTime.now()创建一个当前时间的实例对象
LocalTime localTime = LocalTime.now();
System.out.println(localTime);
使用of(int hour, int minute, int second)
方法创建精准时间的实例
LocalDateTime类
LocalDateTime
是一个不可变的日期时间对象,代表日期时间,通常被视为年 - 月 - 日 - 时 - 分 - 秒。
同样使用LocalDateTime.now()
方法可以创建当前日期+时间的实例对象
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDateTime);
同样of(int year, int month, int dayOfMonth, int hour, int minute, int second)
方法可以指定具体的时间和日期
OffsetDateTime类
OffsetDateTime
是具有偏移量的日期时间的不可变表示,简单来说就是表示日期+时间+偏移量
即OffsetDateTime = LocalDateTime + ZoneOffset
同样OffsetDateTime.now()
方法可以创建当前日期+时间+偏移量的实例对象
OffsetDateTime offsetDateTime = OffsetDateTime.now();
System.out.println(offsetDateTime);//2022-03-13T10:34:33.229680100+08:00
同样of(LocalDate date, LocalTime time, ZoneOffset offset)
方法可以指定具体的时间+日期+偏移量
ZonedDateTime类
ZonedDateTime
是具有时区的日期时间的不可变表示
同样ZonedDateTime.now()
方法可以创建当前日期+时间+时区偏移的实例对象
ZonedDateTime zonedDateTime = ZonedDateTime.now();
System.out.println(zonedDateTime);//结果是2022-03-11T22:50:00.571045100+08:00[Asia/Shanghai]
使用of方法同样可以创建指定时间的ZoneDateTime实例对象,最后一个参数为ZoneId类,ZoneId为时区的标识号
Duration类
Duration
类是基于时间的时间量
使用between
方法计算两个Instant
计算两个瞬间的时间差,返回Duration
类,使用toXXX可以将时间量转为对应单位表示
Instant start = Instant.parse("2022-03-03T10:15:30.00Z");
Instant end = Instant.parse("2022-03-03T11:16:30.00Z");
Duration duration = Duration.between(start, end);
System.out.println(duration);//PT1H1M
System.out.println(duration.toHours());//1
System.out.println(duration.toSeconds());//3900
Period类
Period
是基于年月日的时间量,这个时间量的意思就是他是一个数量,和Duration
类是类似的
可以用of方法创建一个实例
Period period = Period.of(3,40,22);
System.out.println(period);//结果是 P3Y40M22D
常用的方法是between(LocalDate startDateInclusive, LocalDate endDateExclusive)
用于计算两个LocalDate
之间的时间量
这里的时间量是分成了年月日存储在Period里,其中的getDays方法只是获取天数,并不是整个时间量转化成的天数
DateTimeFormatter类
DateTimeFormatter
类用于格式化LocalDateTime
,和SimpleDateFormat
不同,它是线程安全的,可以只创建一个实例,到处引用
创建DateTimeFormatter
时,我们仍然通过传入格式化字符串实现
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
转为指定格式字符串的使用方法和SimpleDateFormat一致,使用format方法
LocalDateTime localDateTime = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
System.out.println(localDateTime);//2022-03-13T00:30:06.734142800
System.out.println(formatter.format(localDateTime));//2022-03-13 00:30
解析字符串时使用LocalDateTime的parse方法
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
String text = "2022-03-13 00:37";
LocalDateTime localDateTime = LocalDateTime.parse(text,formatter);
这里同时附上字符串格式的用法
G 年代标志符
y 年
M 月
d 日
h 时 在上午或下午 (1~12)
H 时 在一天中 (0~23)
m 分
s 秒
S 毫秒
E 星期
D 一年中的第几天
F 一月中第几个星期几
w 一年中第几个星期
W 一月中第几个星期
a 上午 / 下午 标记符
k 时 在一天中 (1~24)
K 时 在上午或下午 (0~11)
z 时区
注意12小时制和24小时制由hh的大小写决定
References
https://blog.csdn.net/f641385712/article/details/112732546
https://blog.csdn.net/l1028386804/article/details/104397090
https://blog.csdn.net/sinat_32849651/article/details/90058050
https://www.cnblogs.com/wbxk/p/9598518.html
https://www.php.cn/java-article-415981.html
https://www.jianshu.com/p/b7e72e585a37