前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java基础学习|学JDK8中的时间类LocalDateTime

Java基础学习|学JDK8中的时间类LocalDateTime

原创
作者头像
Aion
发布2023-12-30 19:06:39
1370
发布2023-12-30 19:06:39
举报

背景

Java里的日期和时间格式化问题,在JDK8(Java SE Development Kit8,以下使用过程中,均称为JDK1.8或者JDK8)以前有很多问题,例如日期类并不提供国际化,没有时区支持,包分配的也比较混乱。所以在JDK8后进行了大改造,索性在rt.jar中新增了一个time包,这样我们就可以个性化设置日期时间的展示方式了。

目前JDK已经到达了JDK 21(Java Development Kit 21),但是在主流的市场上面,使用JDK8的居多。我们现在已经掌握了不少关于日期和时间的操作技巧,但其实随着时间的不断推移,现实的需求也在不断更新,原先的一些API已经难以满足开发需求了。所以从JDK 8之后,为了满足更多的开发需求,Java给我们增加了不少关于日期时间的新特性,接下来本篇文章就带各位来看看这些新特性有哪些。

其他的就不在介绍那么多了,相关的介绍可以参考上两篇文章:LocalDate和LocalTime的详细剖析以及用法都进行了实践,而将LocalDateTime放在最后是因为,他在某些层面上是将上述两个进行了合体以及变相衍生了一些使用方法,所以熟悉上述两个用法后,再来看最后一个类的用法,就很轻松理解。其实三个日期、时间类都是在一起:LocalDate、LocalTime、LocalDateTime,主要是需要先了解前两个,但是我们在实际使用过程中,LocalDate和LocalDateTime却是使用频率最高,也是最长使用的两个类。

类在JDK包的位置

Time API是一组对日期和时间的最重要方面进行建模的包。java. time包中的核心类使用ISO-8601中定义的日历系统(基于公历系统)作为默认日历。当我们引入JDK8后,可以在rt.jar中的java.time目录下找到对应的基础API,打开可以看到有很多新引入的包和类。功能虽多,但是常用的也就是那么几个,所以你想要尽快熟悉,可以自行点击进去查阅,这也是每次写这里都要将这个拿出来,希望大家可以多点击下源码,你会收到不一样的开心。

LocalDateTime架构关系

LocalDateTime是一个最种类,他实现了很多类的接口。实现类有Temporal, TemporalAdjuster, ChronoLocalDateTime<LocalDate>, Serializable。

单一来看,可能看不出来区别,我们将上两篇文章放在一起看,LocalDateLocalTimeLocalDateTime分别实现的类如下:

  • LocalTime

Temporal, TemporalAdjuster, Comparable<LocalTime>, Serializable。

  • LocalDate

Temporal, TemporalAdjuster, ChronoLocalDate, Serializable。

  • LocalDateTime

Temporal, TemporalAdjuster, ChronoLocalDateTime<LocalDate>, Serializable。

从中我们看出来,Temporal, TemporalAdjuster,Serializable是共同实现的接口,我们只需要将不同点讲清楚就可以了。

LocalDateTime时间类实践

1 LocalDateTime自带功能

(1)now()创建日期方法

LocalDateTime在创建日期的时候可以说包含了LocalTime和LocalDate,其中囊括的有年、月、日、时、分、秒、毫秒。

测试代码如下:

代码语言:javascript
复制
    public static void main(String[] args) {
        System.out.println("-- LocalDateTime自带API功能");
        // 当前日期
        System.out.println("LocalDateTime.now() = " + LocalDateTime.now());
        // 衍生出来两个方法,其中一个是从时区获取当前日期,另外一个是从从时钟方式获取
        System.out.println("LocalDateTime.now(ZoneId.of('Asia/Shanghai')) = " + LocalDateTime.now(ZoneId.of("Asia/Shanghai")));
        System.out.println("LocalDateTime.now(Clock.systemDefaultZone()) = " + LocalDateTime.now(Clock.systemDefaultZone()));
		}

测试结果如下:

代码语言:javascript
复制
-- LocalDateTime自带API功能
LocalDateTime.now() = 2023-12-30T17:07:43.519
LocalDateTime.now(ZoneId.of('Asia/Shanghai')) = 2023-12-30T17:07:43.519
LocalDateTime.now(Clock.systemDefaultZone()) = 2023-12-30T17:07:43.519

(2)ofXXX()格式化创建日期方法

在LocalDateTime类中,有如下几个方法,都是根据不同条件来创建一个时间。

测试代码如下:

代码语言:javascript
复制
  	public static void main(String[] args) {
 				// of函数,基础的设定,此处只举例一个
        System.out.println("LocalDateTime.of(2023, 12, 30, 18,26, 34 ) = " + LocalDateTime.of(2023, 12, 30, 18,26, 34 ));
        // of函数,获取一个设定日期,此方法感觉是一个欠揍的方法,但是作为API又不得不存在,他是集成了LocalDate、LocalTime。
        System.out.println("LocalDateTime.of(LocalDate.now(), LocalTime.now() = " + LocalDateTime.of(LocalDate.now(), LocalTime.now()));
        // ofXXX函数
        System.out.println("LocalDateTime.ofInstant(Instant.now(), ZoneId.systemDefault()) = " + LocalDateTime.ofInstant(Instant.now(), ZoneId.systemDefault()));
		}

测试结果如下:

LocalDateTime of(LocalDate date, LocalTime time)获取一个设定日期,此方法感觉是一个欠揍的方法,但是作为API又不得不存在,他是集成了LocalDate和LocalTime。所以提前学习好这里函数,到了LocalDateTime这里就比较好好操作,熟练后就是闭着眼睛也能写出可以跑的代码。

(3)parse转换时间方法

时间转换,同其他函数一样,这里有两个构造,此处只演示一个案例,另外一个还希望多操作实践下。

测试代码如下:

代码语言:javascript
复制
// 转换时间
System.out.println("LocalDateTime.parse(\"2023-12-30T18:26:34\") = " + LocalDateTime.parse("2023-12-30T18:26:34"));

测试结果如下:

代码语言:javascript
复制
LocalDateTime.parse("2023-12-30T18:26:34") = 2023-12-30T18:26:34

注意??:如果你看过前面的文章,可能会发现,在LocalDateTime类中没有提及LocalDate 类中的ofYearDay()方法,也没有提及到LocalTime 类ofNanoOfDay()方法和ofSecondOfDay()方法。如果你知道答案,还望能在评论区说说你的想法。

2 LocalDateTime继承、重写功能

在LocalDateTime中如同LocalDate和LocalTime一样,也有很多继承和重写的方法。

(1)获取字段方法

这里获取的字段其实就是我们在上面的年、月、日、时、分、秒、毫秒、纳秒以及一些常用的本年第几日、本月底几日、本周第几日等。

代码语言:javascript
复制
// getDayOfXXX函数,获取当前日期的星期(英文)、当前日期所在月份中的第几天、当前日期所在年份中的第几天
System.out.println("LocalDateTime.now().getDayOfWeek() = " + LocalDateTime.now().getDayOfWeek());
System.out.println("LocalDateTime.now().getDayOfMonth() = " + LocalDateTime.now().getDayOfMonth());
System.out.println("LocalDateTime.now().getDayOfYear() = " + LocalDateTime.now().getDayOfYear());

测试打印结果:

代码语言:javascript
复制
LocalDateTime.now().getDayOfWeek() = SATURDAY
LocalDateTime.now().getDayOfMonth() = 30
LocalDateTime.now().getDayOfYear() = 364

(2)withXXX()方法

LocalDateTime中的withXXX方法涵盖了LocalDate和LocalTime中的withXXX方法。

测试代码如下:

代码语言:javascript
复制
// withXXX函数
// 返回当前月、周、年的星期几。例如返回当前月的第一天、返回本周的星期二、星期三的时间
System.out.println("LocalDateTime.now().with(LocalDate.now())) = " + LocalDateTime.now().with(LocalDate.now()));
System.out.println("LocalDateTime.now().with(ChronoField.DAY_OF_MONTH, 1)) = " + LocalDateTime.now().with(ChronoField.DAY_OF_MONTH, 1));
System.out.println("LocalDateTime.now().with(ChronoField.DAY_OF_WEEK, 2) = " + LocalDateTime.now().with(ChronoField.DAY_OF_WEEK, 2));
System.out.println("LocalDateTime.now().with(ChronoField.DAY_OF_WEEK, 3) = " + LocalDateTime.now().with(ChronoField.DAY_OF_WEEK, 3));
// 主要是月份的设置,例如设置10月份,当前时间的10号,当前时间的6点,那么就返回当前日期的副本且只修改数据。
System.out.println("LocalDateTime.now().withMonth(10) = " + LocalDateTime.now().withMonth(10));
System.out.println("LocalDateTime.now().withDayOfMonth(10)) = " + LocalDateTime.now().withDayOfMonth(10));
System.out.println("LocalDateTime.now().withHour(6)) = " + LocalDateTime.now().withHour(6));

测试结果如下:

代码语言:javascript
复制
LocalDateTime.now().with(LocalDate.now())) = 2023-12-30T18:06:51.464
LocalDateTime.now().with(ChronoField.DAY_OF_MONTH, 1)) = 2023-12-01T18:06:51.464
LocalDateTime.now().with(ChronoField.DAY_OF_WEEK, 2) = 2023-12-26T18:06:51.464
LocalDateTime.now().with(ChronoField.DAY_OF_WEEK, 3) = 2023-12-27T18:06:51.465
LocalDateTime.now().withMonth(10) = 2023-10-30T18:06:51.465
LocalDateTime.now().withDayOfMonth(10)) = 2023-12-10T18:06:51.465
LocalDateTime.now().withHour(6)) = 2023-12-30T06:06:51.465

(3)isXXX()判断方法

LocalDateTime中的判断方法主要有

  • 在某个之前
  • 在某个时间之后
  • 是否等于
  • 是否在有效范围内/JDK设定的范围是否符合

咿呀,感觉是否又少了一个判断是否是闰年?哦,这个只在LocalDate中存在,在LocalDateTime和LocalTime并不存在。此时,我们从另外一个方面看待这个问题,其实就比较好理解了。

闰年,只是在日期中存在,在时间这个概念上面不存在;LocalDateTime兼容的度最小颗粒是时间,所以LocalDateTime和LocalTime是时间类,而LocalDate是日期类。所以在LocalDateTime中是没有闰年的判断的。有些时间我们也常常说,LocalDateTime为长时间,而LocalTime短时间也是这个道理。

(4)plusXXX()/minusXXX()方法

在LocalDateTime中,加法和减法是相互呼应的。可以参考表情的方法或者JDK中的方法进行参数设定,即可以使用。

测试代码如下:

代码语言:javascript
复制
// 日期加减,主要有两种类型:第一种是直接进行加减、使用TemporalAmount参数设定;第二种就是直接设定具体的参数
// 方式一 在当前日期增加3个周期,周期单位为天
System.out.println("LocalDateTime.now().plus(Period.ofDays(3)) = " + LocalDateTime.now().plus(Period.ofDays(3)));
// 方式二 在当前日期增加4天,在当前日期减少2周
System.out.println("LocalDateTime.now().plusDays(3) = " + LocalDateTime.now().plusDays(4));
System.out.println("LocalDateTime.now().minusWeeks(2) = " + LocalDateTime.now().minusWeeks(2));

测试结果如下:

代码语言:javascript
复制
LocalDateTime.now().plus(Period.ofDays(3)) = 2024-01-02T18:06:51.466
LocalDateTime.now().plusDays(3) = 2024-01-03T18:06:51.466
LocalDateTime.now().minusWeeks(2) = 2023-12-16T18:06:51.466

总结

在JDK8之前我们都是使用Date或者Calendar来做计算或者转换,自从有了JDK8,我们的CVX速度很明显增强了。JDK8引入了许多新的特性和改进,使得代码编写更加简洁、可读性更高,并且提供了更好的性能和并发处理能力。


我正在参与2023腾讯技术创作特训营第四期有奖征文,快来和我瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 类在JDK包的位置
  • LocalDateTime架构关系
  • LocalDateTime时间类实践
    • 1 LocalDateTime自带功能
      • (1)now()创建日期方法
      • (2)ofXXX()格式化创建日期方法
      • (3)parse转换时间方法
    • 2 LocalDateTime继承、重写功能
      • (1)获取字段方法
      • (2)withXXX()方法
      • (3)isXXX()判断方法
      • (4)plusXXX()/minusXXX()方法
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com