作者:到处旅游增加阅历入 | 来源:互联网 | 2023-10-12 18:57
在JDK1.8之前,日期和时间的处理一直是Java里面经常被吐槽的问题,相信使用过Date和Calendar的人都有深刻的感觉,不管你是要进行日期和时间的计算或者相互比较,在使用Date和Calendar时都表现的很麻烦,总之一句话就是不好用。
以至于在JDK1.8之前,很多人都选择使用joda-time来进行日期和时间的处理,joda-time对日期和时间的处理进行了封装,使日期和时间的处理变得简单
在JDK1.8中引入java.time.*包,重新定义了一套日期时间处理类, 让日期时间的处理变得简单易用
在介绍java.time包之前,先来聊一些基础概念,大家在处理时间的过程中,一定处理过时区,北京时间需要加8小时,相信只要开发过程中处理过时间,都会有这样一个操作,那为什么北京时间需要加8小时呢?
说来惭愧,在写这篇博文之前,我没有搞清楚这里面的逻辑,只知道北京属于东八区,需要加8小时,下面我们一起来看一下~
UTC 协调世界时(Coordinated Universal Time)又称世界统一时间、世界标准时间,由于英文(CUT)和法文(TUC)的缩写不同,作为妥协,简称UTC。
时区 由于世界各国家与地区经度不同,地方时也有所不同,因此会划分为不同的时区
地球是自西向东自转,东边比西边先看到太阳,东边的时间也比西边的早。东边时刻与西边时刻的差值不仅要以时计,而且还要以分和秒来计算,这给人们带来不便
为了克服时间上的混乱,1884年在华盛顿召开的一次国际经度会议(又称国际子午线会议)上,规定将全球划分为24个时区(东、西各12个时区)。规定英国(格林尼治天文台旧址)为中时区(零时区)、东1—12区,西1—12区。每个时区横跨经度15度,时间正好是1小时。最后的东、西第12区各跨经度7.5度,以东、西经180度为界。每个时区的中央经线上的时间就是这个时区内统一采用的时间,称为区时,相邻两个时区的时间相差1小时 《摘自百度百科》
因为北京属于东8区,所以需要在世界统一时间(UTC)的基础上加8小时
java.time包简介 java.time包主要提供了日期、时间、瞬间、持续时间的api
主要的日期时间概念,包括时刻,持续时间,日期,时间,时区和时段。 基于ISO日历系统,所有的类都是不可变的,线程安全的
按类型主要分为:
日期和时间 Instant本质上是一个数字时间戳。 LocalDate存储没有时间的日期,如2010-07-09 LocalTime 存储没有日期的时间,如22:18 LocalDateTime 存储日期和时间。如2020-07-09T22:18 ZonedDateTime 存储带时区的日期和时间 期限 Duration 存储期间和持续时间。以纳秒为单位的时间线的简单测量 附加的类型 Month 存储一个月。如“十一月” DayOfWeek 存储一周中的一天,如“Tuesday” Year 存储年,如“2020” YearMonth 存储年和月,如“2020-10”,可用于信用卡上的到期 MonthDay 存储月和日,如“12-14”,可用于存储生日 OffsetTime 存储与UTC没有日期的时间和偏移量 OffsetDateTime存储与UTC的日期时间和偏移量 下面来分别看一下各自的用法
Instant Instant表示的是时间线上的瞬间点,本质上就是时间戳
Instant instant = Instant. now ( ) ; System. out. println ( instant) ; System. out. println ( instant. atZone ( ZoneId. systemDefault ( ) ) ) ; System. out. println ( instant. getEpochSecond ( ) ) ; System. out. println ( instant. toEpochMilli ( ) ) ; Instant instant1 = Instant. ofEpochMilli ( new Date ( ) . getTime ( ) ) ; System. out. println ( instant1) ; Instant instant2 = Instant. parse ( "2020-07-10T12:52:56.053Z" ) ; System. out. println ( instant2) ; Instant instant3 = Instant. now ( Clock. systemUTC ( ) ) ; System. out. println ( instant3) ; System. out. println ( instant. plus ( 3 , ChronoUnit. HOURS) ) ; System. out. println ( instant) ; Instant ins1 = Instant. parse ( "2020-07-10T12:52:56.053Z" ) ; Instant ins2 = Instant. parse ( "2020-07-10T12:52:46.034Z" ) ; System. out. println ( ins1. isAfter ( ins2) ) ; System. out. println ( ins1. isBefore ( ins2) ) ;
LocalDate LocalDate是一个不可变的日期时间对象,存储没有时间的日期
LocalDate localDate = LocalDate. now ( ) ; System. out. println ( localDate) ; LocalDate localDate1 = LocalDate. now ( Clock. systemDefaultZone ( ) ) ; System. out. println ( localDate1) ; LocalDate localDate2 = LocalDate. of ( 2020 , 5 , 1 ) ; System. out. println ( localDate2) ; LocalDate localDate3 = LocalDate. parse ( "2020-05-04" ) ; System. out. println ( localDate3) ; LocalDate localDate4 = LocalDate. parse ( "20200205" , DateTimeFormatter. ofPattern ( "yyyyMMdd" ) ) ; System. out. println ( localDate4) ; LocalDate localDate5 = LocalDate. ofYearDay ( 2020 , 100 ) ; System. out. println ( localDate5) ; System. out. println ( localDate. plusDays ( 4 ) ) ; System. out. println ( localDate. plus ( 4 , ChronoUnit. DAYS) ) ; System. out. println ( localDate. plusWeeks ( 2 ) ) ; System. out. println ( localDate. plusMonths ( 2 ) ) ; System. out. println ( localDate. plusYears ( 2 ) ) ; System. out. println ( localDate. plusDays ( - 3 ) ) ; System. out. println ( localDate. minusDays ( 3 ) ) ; System. out. println ( localDate. plusDays ( 4 ) . getDayOfWeek ( ) ) ; System. out. println ( localDate. getDayOfMonth ( ) ) ; System. out. println ( localDate. getDayOfYear ( ) ) ; System. out. println ( localDate. format ( DateTimeFormatter. ofPattern ( "yyyy/MM/dd" ) ) ) ; System. out. println ( localDate. isLeapYear ( ) ) ; System. out. println ( localDate. lengthOfMonth ( ) ) ; System. out. println ( localDate. lengthOfYear ( ) ) ;
LocalTime LocalTime是一个不可变的日期时间对象,存储没有日期的时间
LocalTime localTime = LocalTime. now ( ) ; System. out. println ( localTime) ; System. out. println ( LocalTime. of ( 12 , 11 ) ) ; System. out. println ( LocalTime. of ( 12 , 11 , 45 ) ) ; System. out. println ( localTime. plusHours ( 2 ) ) ; . . .
LocalDateTime LocalDateTime是一个不可变的日期时间对象,代表日期时间
LocalDateTime localDateTime = LocalDateTime. now ( ) ; System. out. println ( localDateTime) ; System. out. println ( localDateTime. format ( DateTimeFormatter. ofPattern ( "yyyy-MM-dd hh:mm:ss" ) ) ) ; System. out. println ( localDateTime. plusDays ( 10 ) . getDayOfWeek ( ) ) ; System. out. println ( localDateTime. plusMinutes ( 17 ) ) ;
LocalDateTime相当于是结合了LocalDate和LocalTime,方法和功能也都是一样的
ZonedDateTime ZonedDateTime是具有时区的日期时间的不可变表示
ZonedDateTime zonedDateTime = ZonedDateTime. now ( ) ; System. out. println ( zonedDateTime) ; System. out. println ( zonedDateTime. toLocalDate ( ) ) ; System. out. println ( zonedDateTime. toLocalDateTime ( ) ) ; System. out. println ( zonedDateTime. toLocalTime ( ) ) ; System. out. println ( zonedDateTime. plusDays ( 3 ) ) ; System. out. println ( zonedDateTime. format ( DateTimeFormatter. ofPattern ( "yyyy-MM-dd hh:mm:ss" ) ) ) ;
Duration Duration描述的其实是时长,表示一个时间区间
Duration duration = Duration. of ( 5 , ChronoUnit. DAYS) ; System. out. println ( duration) ; System. out. println ( Duration. ofHours ( 3 ) ) ; System. out. println ( Duration. of ( 5 , ChronoUnit. DAYS) . toHours ( ) ) ; System. out. println ( duration. plusHours ( 8 ) . toHours ( ) ) ;
其他类型 上面已经介绍了常用的日期时间类型的使用,基本上日常的使用通过上面的几个类就够用了,其他类型(Month、DayOfWeek、Year、YearMonth、MonthDay、OffsetTime、OffsetDateTime)的用法都是大同小异,看一下api基本都会了
总结 从上面一些类的用法,可以看出JDK1.8对日期时间类的处理定义了很多类,用来表示不同的日期时间使用场景,基本上我们常用到的场景,都有定义不同的类,通过这些类可以很方便的操作日期和时间。
如果感觉对你有些帮忙,请收藏好,你的关注和点赞是对我最大的鼓励! 如果想跟我一起学习,坚信技术改变世界,请关注【Java天堂】公众号,我会定期分享自己的学习成果,第一时间推送给您