深入了解Java8新特性-日期时间API之TemporalAdjusters与TemporalAdjuster

本文主要是介绍深入了解Java8新特性-日期时间API之TemporalAdjusters与TemporalAdjuster,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

阅读建议

嗨,伙计!刷到这篇文章咱们就是有缘人,在阅读这篇文章前我有一些建议:

  1. 本篇文章大概10000多字,预计阅读时间长需要10分钟。
  2. 本篇文章的实战性、理论性较强,是一篇质量分数较高的技术干货文章,建议收藏起来,方便时常学习与回顾,温故而知新。
  3. 创作不易,免费的点赞、关注,请走上一走,算是对博主一些鼓励,让我更有动力输出更多的干货内容。

注意

本文编写的单元测试是基于java11,具体的版本号是:11.0.19

TemporalAdjusters与TemporalAdjuster

TemporalAdjuster

TemporalAdjuster是Java 8中引入的新的日期时间API的一部分,是一个函数式接口。它能够执行复杂的日期操作,例如,可以获得下一个星期日、当月的最后一天或下一年的第一天。TemporalAdjuster只有一个带Temporal对象参数的抽象方法adjustInto(),可以通过向其传递Temporal对象在其任何实现中调用它。在TemporalAdjusters类中有许多预定义的实现,例如LocalDate、LocalDateTime等。

@FunctionalInterface
public interface TemporalAdjuster {Temporal adjustInto(Temporal temporal);
}

TemporalAdjusters

TemporalAdjusters也是Java 8中处理日期时间的工具类,但它的功能和TemporalAdjuster有所不同。TemporalAdjusters是一个静态工具类,提供了很多静态方法来创建TemporalAdjuster对象,这些方法可以用于对日期时间进行一些常用的调整操作,例如获取本月的第一天、下个月的第一天、本年的第一天或最后一天等。这些方法返回的TemporalAdjuster对象可以用于对日期时间进行相应的调整操作。

功能作用

TemporalAdjusters与TemporalAdjuster的作用在于提供了一种统一的、类型安全的方式来处理日期时间的操作。在过去的版本中,Java的日期时间API主要依赖于Calendar类,但这个类在处理复杂的日期时间操作时显得不够灵活和类型安全。TemporalAdjusters的出现弥补了这一缺陷,使得日期时间操作更加简洁、易用和类型安全。

TemporalAdjusters的意义在于它为Java日期时间API注入了更多的活力,使其更加适应现代应用程序的需求。通过TemporalAdjusters,开发人员可以更方便地处理日期时间的各种操作,例如添加或减去一定的时间量、获取特定时间单位的值、将日期时间转换为不同的格式等等。此外,TemporalAdjusters还支持链式调用,使得对日期时间的操作更加流畅和直观。

使用场景分析

TemporalAdjusters的使用场景非常广泛,可以应用于各种需要调整日期时间的场景。以下是一些常见的使用场景:

  • 计算日期时间差值:TemporalAdjusters提供了一组方法,可以轻松地计算两个日期时间之间的差值,例如计算两个日期之间的天数、小时数或分钟数等。
  • 获取特定时间单位的值:使用TemporalAdjusters可以方便地获取日期时间的特定时间单位的值,例如获取当前日期的年份、月份、日期等。
  • 调整日期时间:TemporalAdjusters提供了一组方法,可以对日期时间进行调整,例如在日期上添加或减去一定的时间量、将日期时间转换为不同的格式等。
  • 解析日期时间字符串:TemporalAdjusters可以用于解析日期时间字符串,并将其转换为Temporal对象。这使得开发人员可以更方便地处理日期时间的字符串表示形式。
  • 时区转换:TemporalAdjusters提供了一些方法,可以将日期时间从一个时区转换为另一个时区。这对于国际化应用程序来说非常有用,可以方便地处理不同时区之间的日期时间转换。

核心方法

TemporalAdjusters#ofDateAdjuster(...)

TemporalAdjusters.ofDateAdjuster(...) 它接受一个函数作为参数,该函数接受一个日期时间对象并返回一个新的日期时间对象,表示对该日期时间对象进行某种调整后的结果。这个方法返回一个TemporalAdjuster对象,可以用于对日期时间对象进行相应的调整操作。通常情况下,这个方法用于创建自定义的TemporalAdjuster对象,以执行一些复杂的日期时间调整操作。

@Test
public void test() {UnaryOperator<LocalDate> unaryOperator = item -> item.minusDays(1);//日期调节逻辑:减去1天TemporalAdjuster temporalAdjuster = TemporalAdjusters.ofDateAdjuster(unaryOperator);//构造日期调节器类LocalDate localDate1 = LocalDate.of(2023, 11, 22);//日期:2023-11-22LocalDate localDate2 = localDate1.with(temporalAdjuster);//执行调节逻辑,并返回调节后结果System.out.println(localDate2);//输出结果:2023-11-21
}

TemporalAdjusters#firstDayOfMonth()

TemporalAdjusters.firstDayOfMonth()是一个静态方法,用于创建一个 TemporalAdjuster 对象,该对象可以用于将给定的日期调整为本月的第一天。

这个方法返回的 TemporalAdjuster 对象可以与任何实现了 java.time.temporal.Temporal 接口的对象一起使用,例如 LocalDate、LocalDateTime、ZonedDateTime 等。使用 with 方法将 TemporalAdjuster 应用于这些对象,可以对日期进行调整。

@Test
public void test1() {TemporalAdjuster temporalAdjuster = TemporalAdjusters.firstDayOfMonth();LocalDateTime localDateTime = LocalDateTime.of(2023, 11, 12, 13, 1, 12);LocalDateTime localDateTime1 = localDateTime.with(temporalAdjuster);System.out.println(localDateTime1);//输出结果:2023-11-01T13:01:12
}

TemporalAdjusters#lastDayOfMonth()

TemporalAdjusters.lastDayOfMonth()是一个静态工厂方法,用于创建一个 TemporalAdjuster 对象,该对象可以用于将给定的日期调整为本月的最后一天。这个方法返回的 TemporalAdjuster 对象可以与任何实现了 java.time.temporal.Temporal 接口的对象一起使用,例如 LocalDate、LocalDateTime、ZonedDateTime 等。使用 with 方法将 TemporalAdjuster 应用于这些对象,可以对日期进行调整。

@Test
public void test2() {TemporalAdjuster temporalAdjuster = TemporalAdjusters.lastDayOfMonth();LocalDate localDate = LocalDate.of(2023, 2, 1);LocalDate localDate1 = localDate.with(temporalAdjuster);System.out.println(localDate1);//输出结果:2023-02-28
}

TemporalAdjusters#firstDayOfNextMonth()

TemporalAdjusters.firstDayOfNextMonth() 是一个静态工厂方法,用于创建一个 TemporalAdjuster 对象,该对象可以用于将给定的日期调整为下一个月的第一天。这个方法返回的 TemporalAdjuster 对象可以与任何实现了 java.time.temporal.Temporal 接口的对象一起使用,例如 LocalDate、LocalDateTime、ZonedDateTime 等。使用 with 方法将 TemporalAdjuster 应用于这些对象,可以对日期进行调整。

@Test
public void test3() {TemporalAdjuster temporalAdjuster = TemporalAdjusters.firstDayOfNextMonth();LocalDate localDate = LocalDate.of(2023, 2, 1);LocalDate localDate1 = localDate.with(temporalAdjuster);System.out.println(localDate1);//输出结果:2023-03-01
}

TemporalAdjusters#firstDayOfYear()

TemporalAdjusters.firstDayOfYear() 是一个静态工厂方法,用于创建一个 TemporalAdjuster 对象,该对象可以用于将给定的日期调整为本年的第一天。这个方法返回的 TemporalAdjuster 对象可以与任何实现了 java.time.temporal.Temporal 接口的对象一起使用,例如 LocalDate、LocalDateTime、ZonedDateTime 等。使用 with 方法将 TemporalAdjuster 应用于这些对象,可以对日期进行调整。

@Test
public void test4() {TemporalAdjuster temporalAdjuster = TemporalAdjusters.firstDayOfYear();LocalDate localDate = LocalDate.of(2023, 2, 1);LocalDate localDate1 = localDate.with(temporalAdjuster);System.out.println(localDate1);//输出结果:2023-01-01
}

TemporalAdjusters#lastDayOfYear()

TemporalAdjusters.lastDayOfYear() 是 一个静态工厂方法,用于创建一个 TemporalAdjuster 对象,该对象可以用于将给定的日期调整为本年的最后一天。这个方法返回的 TemporalAdjuster 对象可以与任何实现了 java.time.temporal.Temporal 接口的对象一起使用,例如 LocalDate、LocalDateTime、ZonedDateTime 等。使用 with 方法将 TemporalAdjuster 应用于这些对象,可以对日期进行调整。

@Test
public void test5() {TemporalAdjuster temporalAdjuster = TemporalAdjusters.lastDayOfYear();LocalDate localDate = LocalDate.of(2023, 2, 1);LocalDate localDate1 = localDate.with(temporalAdjuster);System.out.println(localDate1);//输出结果:2023-12-31
}

TemporalAdjusters#firstDayOfNextYear()

TemporalAdjusters.firstDayOfNextYear() 是一个静态工厂方法,用于创建一个 TemporalAdjuster 对象,该对象可以用于将给定的日期调整为下一年度的第一天。这个方法返回的 TemporalAdjuster 对象可以与任何实现了 java.time.temporal.Temporal 接口的对象一起使用,例如 LocalDate、LocalDateTime、ZonedDateTime 等。使用 with 方法将 TemporalAdjuster 应用于这些对象,可以对日期进行调整。

@Test
public void test6() {TemporalAdjuster temporalAdjuster = TemporalAdjusters.firstDayOfNextYear();LocalDate localDate = LocalDate.of(2023, 2, 1);LocalDate localDate1 = localDate.with(temporalAdjuster);System.out.println(localDate1);//输出结果:2024-01-01
}

TemporalAdjusters#firstInMonth(...)

TemporalAdjusters.firstInMonth() 是 Java 8 中 java.time.temporal.TemporalAdjusters 类的一个静态工厂方法,用于创建一个 TemporalAdjuster 对象,该对象可以用于将给定的日期调整为本月的第一个星期几。这个方法接受一个 DayOfWeek 类型的参数,用于指定要调整到的星期几。例如,如果想要将日期调整为当前日期月份的第一个星期二,可以这样使用:

@Test
public void test7() {DayOfWeek dayOfWeek = DayOfWeek.of(2);TemporalAdjuster temporalAdjuster = TemporalAdjusters.firstInMonth(dayOfWeek);LocalDate localDate = LocalDate.of(2023, 2, 1);LocalDate localDate1 = localDate.with(temporalAdjuster);System.out.println(localDate1);//输出结果:2023-02-07
}

TemporalAdjusters#lastInMonth(...)

TemporalAdjusters.lastInMonth() 是一个静态工厂方法,用于创建一个 TemporalAdjuster 对象,该对象可以用于将给定的日期调整为本月的最后一个星期几。这个方法接受一个 DayOfWeek 类型的参数,用于指定要调整到的星期几。例如,如果想要将日期调整为本月的最后一个星期二,可以这样使用:

@Test
public void test8() {DayOfWeek dayOfWeek = DayOfWeek.of(2);TemporalAdjuster temporalAdjuster = TemporalAdjusters.lastInMonth(dayOfWeek);LocalDate localDate = LocalDate.of(2023, 2, 1);LocalDate localDate1 = localDate.with(temporalAdjuster);System.out.println(localDate1);//输出结果:2023-02-28
}

TemporalAdjusters#dayOfWeekInMonth(...)

TemporalAdjusters.dayOfWeekInMonth() 是一个静态工厂方法,用于调整日期的静态方法。这个方法可以用来将给定的日期调整为指定月份中的指定星期几的日期。

这个方法接受两个参数:

  • ordinal - 一个整数,表示月份中的第几天。范围从 1(月份的第一天)到 28、29、30 或 31(根据月份和年份而定)。
  • dayOfWeek - 一个 DayOfWeek 枚举值,表示要调整到的星期几。例如,DayOfWeek.MONDAY 表示星期一。

使用这个方法,你可以将日期调整到指定月份的特定星期几。例如,如果你想将日期调整到 11 月的第一个星期三,你可以这样使用:

@Test
public void test9() {DayOfWeek dayOfWeek = DayOfWeek.of(3);TemporalAdjuster temporalAdjuster = TemporalAdjusters.dayOfWeekInMonth(1, dayOfWeek);LocalDate localDate = LocalDate.of(2023, 11, 30);LocalDate localDate1 = localDate.with(temporalAdjuster);System.out.println(localDate1);//输出结果:2023-11-01
}

TemporalAdjusters#next(...)

TemporalAdjusters.next(DayOfWeek dayOfWeek) 是一个用于调整日期的静态方法,这个方法可以用来将给定的日期调整到下一个指定星期几。这个方法接受一个 DayOfWeek 参数,表示要调整到的星期几。例如,DayOfWeek.MONDAY 表示星期一。使用这个方法,你可以将日期调整到下一个特定星期几。例如,如果你想将日期调整到下一个星期日,你可以这样使用:

@Test
public void test10() {DayOfWeek dayOfWeek = DayOfWeek.SUNDAY;TemporalAdjuster temporalAdjuster = TemporalAdjusters.next(dayOfWeek);LocalDate localDate = LocalDate.of(2023, 12, 3);LocalDate localDate1 = localDate.with(temporalAdjuster);System.out.println(localDate1);//输出结果:2023-12-10
}

TemporalAdjusters#nextOrSame(...)

TemporalAdjusters.nextOrSame(DayOfWeek dayOfWeek) 是一个用于调整日期的静态方法,这个方法可以用来将给定的日期调整到下一个或相同的星期几。这个方法接受一个 DayOfWeek 参数,表示要调整到的星期几。例如,DayOfWeek.MONDAY 表示星期一。

TemporalAdjusters#nextOrSame(...)与TemporalAdjusters#next(...)区别在于:TemporalAdjusters.nextOrSame(DayOfWeek dayOfWeek) 方法将给定的日期调整到下一个或相同的星期几。这意味着,如果给定的日期已经是星期几,那么调整后的日期将与原始日期相同。否则,调整后的日期将是下一个星期几。TemporalAdjusters.next(DayOfWeek dayOfWeek) 方法将给定的日期调整到下一个星期几,不考虑原始日期是否已经是指定星期几。

假如当前日期是2023年11月30日星期四,返回下一周星期四的日期,使用TemporalAdjusters#nextOrSame(...),返回结果是2023-12-07;而使用TemporalAdjusters#nextOrSame(...)返回的则是其本身2023-11-30,除了这种特殊情况外,其余则是等同的。

@Test
public void test11() {DayOfWeek dayOfWeek = DayOfWeek.of(4);TemporalAdjuster temporalAdjuster = TemporalAdjusters.next(dayOfWeek);LocalDate localDate = LocalDate.of(2023, 11, 30);LocalDate localDate1 = localDate.with(temporalAdjuster);System.out.println(localDate1);//输出结果:2023-12-07TemporalAdjuster temporalAdjuster1 = TemporalAdjusters.nextOrSame(dayOfWeek);LocalDate localDate2 = LocalDate.of(2023, 11, 30);LocalDate localDate3 = localDate2.with(temporalAdjuster1);System.out.println(localDate3);//输出结果:2023-11-30
}

TemporalAdjusters#previous(...)

TemporalAdjusters.previous(DayOfWeek dayOfWeek) 是一个用于调整日期的静态方法,这个方法可以用来将给定的日期调整到上一个星期几。这个方法接受一个 DayOfWeek 参数,表示要调整到的星期几。例如,DayOfWeek.MONDAY 表示星期一。

使用这个方法,你可以将日期调整到上一个或同一天的特定星期几。例如,如果你想将日期调整到上一个周的星期三,你可以这样使用:

@Test
public void test12() {DayOfWeek dayOfWeek = DayOfWeek.of(3);TemporalAdjuster temporalAdjuster = TemporalAdjusters.previous(dayOfWeek);LocalDate localDate = LocalDate.of(2023, 11, 1);LocalDate localDate1 = localDate.with(temporalAdjuster);System.out.println(localDate1);//输出结果:2023-10-25
}

TemporalAdjusters#previousOrSame(...)

TemporalAdjusters#previousOrSame(DayOfWeek dayOfWeek) 是一个用于调整日期的静态方法,这个方法可以用来将给定的日期调整到上一个或相同的星期几。这个方法接受一个 DayOfWeek 参数,表示要调整到的星期几。例如,DayOfWeek.MONDAY 表示星期一。

TemporalAdjusters#previousOrSame(...)和TemporalAdjusters#previous(...)的区别,与上面的TemporalAdjusters#nextOrSame(...)与TemporalAdjusters#next(...)区别是类似的,不过是上面是下一周,这里是上一周。

使用这个方法,你可以将日期调整到上一个或同一天的特定星期几。例如,如果你想将日期调整到上一个或同一天的星期三,你可以这样使用:

@Test
public void test13() {DayOfWeek dayOfWeek = DayOfWeek.of(3);TemporalAdjuster temporalAdjuster = TemporalAdjusters.previous(dayOfWeek);LocalDate localDate = LocalDate.of(2023, 11, 1);LocalDate localDate1 = localDate.with(temporalAdjuster);System.out.println(localDate1);//输出结果:2023-10-25TemporalAdjuster temporalAdjuster1 = TemporalAdjusters.nextOrSame(dayOfWeek);LocalDate localDate2 = LocalDate.of(2023, 11, 1);LocalDate localDate3 = localDate2.with(temporalAdjuster1);System.out.println(localDate3);//输出结果:2023-11-01
}

这篇关于深入了解Java8新特性-日期时间API之TemporalAdjusters与TemporalAdjuster的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/440620

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

服务器集群同步时间手记

1.时间服务器配置(必须root用户) (1)检查ntp是否安装 [root@node1 桌面]# rpm -qa|grep ntpntp-4.2.6p5-10.el6.centos.x86_64fontpackages-filesystem-1.41-1.1.el6.noarchntpdate-4.2.6p5-10.el6.centos.x86_64 (2)修改ntp配置文件 [r

关于数据埋点,你需要了解这些基本知识

产品汪每天都在和数据打交道,你知道数据来自哪里吗? 移动app端内的用户行为数据大多来自埋点,了解一些埋点知识,能和数据分析师、技术侃大山,参与到前期的数据采集,更重要是让最终的埋点数据能为我所用,否则可怜巴巴等上几个月是常有的事。   埋点类型 根据埋点方式,可以区分为: 手动埋点半自动埋点全自动埋点 秉承“任何事物都有两面性”的道理:自动程度高的,能解决通用统计,便于统一化管理,但个性化定

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06