《Java8实战》第12章 新的日期和时间 API

news/2025/2/14 0:12:07/

原来的Java的时间类Date、java.util.Calendar类都不太好,以语言无关方式格式化和解析日期或时间的 DateFormat 方法也有线程安全的问题

12.1 LocalDate、LocalTime、LocalDateTime、Instant、Duration 以及 Period

12.1.1 使用 LocalDate 和 LocalTime

LocalDate 类,该类的实例是一个不可变对象,它只提供了简单的日期,并不含当天的时间信息。另外,它也不附带任何与时区相关的信息。

LocalDate date = LocalDate.of(2017, 9, 21); // 2017-09-21
int year = date.getYear(); 2017
Month month = date.getMonth(); SEPTEMBER
int day = date.getDayOfMonth(); 21
DayOfWeek dow = date.getDayOfWeek(); THURSDAY
int len = date.lengthOfMonth(); 30 (days in September)
boolean leap = date.isLeapYear(); false (not a leap year)

还可以使用工厂方法 now 从系统时钟中获取当前的日期:
LocalDate today = LocalDate.now();
还可以通过传递一个 TemporalField 参数给 get 方法访问同样的信息。
使用 TemporalField 读取 LocalDate 的值

int year = date.get(ChronoField.YEAR); 
int month = date.get(ChronoField.MONTH_OF_YEAR); 
int day = date.get(ChronoField.DAY_OF_MONTH);
或者
int year = date.getYear(); 
int month = date.getMonthValue(); 
int day = date.getDayOfMonth();LocalDate date = LocalDate.parse("2017-09-21");

12.1.2 合并日期和时间

这个复合类名叫 LocalDateTime,是 LocalDate 和 LocalTime 的合体。它同时表示了日期和时间,但不带有时区信息,你可以直接创建,也可以通过合并日期和时间对象创建

LocalDateTime dt1 = LocalDateTime.of(2014, Month.SEPTEMBER, 21, 13, 45, 20); 
LocalDateTime dt2 = LocalDateTime.of(date, time); 
LocalDateTime dt3 = date.atTime(13, 45, 20); 
LocalDateTime dt4 = date.atTime(time); 
LocalDateTime dt5 = time.atDate(date); LocalDate date1 = dt1.toLocalDate(); 
LocalTime time1 = dt1.toLocalTime(); 

12.1.3 机器的日期和时间格式

12.1.4 定义 Duration 或 Period

Duration 类的静态工厂方法 between 就是为这个目的而设计的。

Duration d1 = Duration.between(time1, time2); 
Duration d1 = Duration.between(dateTime1, dateTime2); 
Duration d2 = Duration.between(instant1, instant2); 

由于 LocalDateTime 和 Instant 是为不同的目的而设计的,一个是为了便于人阅读使用,另一个是为了便于机器处理,因此不能将二者混用。如果你试图在这两类对象之间创建Duration,就会触发一个 DateTimeException 异常。

12.2 操纵、解析和格式化日期

如果你已经有一个 LocalDate 对象,想要创建它的一个修改版,最直接也最简单的方法是使用 withAttribute 方法。withAttribute 方法会创建对象的一个副本,并按照需要修改它的属性。

LocalDate date1 = LocalDate.of(2017, 9, 21); 
LocalDate date2 = date1.withYear(2011); 
LocalDate date3 = date2.withDayOfMonth(25); 
LocalDate date4 = date3.with(ChronoField.MONTH_OF_YEAR, 2); 

采用更通用的 with 方法能达到同样的目的,它接受的第一个参数是一个 TemporalField对象
加一段时间,或者减一段时间,plus

LocalDate date1 = LocalDate.of(2017, 9, 21); 
LocalDate date2 = date1.plusWeeks(1); 
LocalDate date3 = date2.minusYears(6); 
LocalDate date4 = date3.plus(6, ChronoUnit.MONTHS);

image.png

12.2.1 使用 TemporalAdjuster

import static java.time.temporal.TemporalAdjusters.*; 
LocalDate date1 = LocalDate.of(2014, 3, 18); 2014-03-18 
LocalDate date2 = date1.with(nextOrSame(DayOfWeek.SUNDAY)); 2014-03-23
LocalDate date3 = date2.with(lastDayOfMonth()); 2014-03-31

image.png

12.2.2 打印输出及解析日期–时间对象

新的java.time.format 包就是特别为这个目的而设计的

LocalDate date = LocalDate.of(2014, 3, 18); 
String s1 = date.format(DateTimeFormatter.BASIC_ISO_DATE); 20140318
String s2 = date.format(DateTimeFormatter.ISO_LOCAL_DATE); 2014-03-18LocalDate date1 = LocalDate.parse("20140318", DateTimeFormatter.BASIC_ISO_DATE); 
LocalDate date2 = LocalDate.parse("2014-03-18", DateTimeFormatter.ISO_LOCAL_DATE); 

12.3 处理不同的时区和历法

12.3.1 使用时区

时区是按照一定的规则将区域划分成的标准时间相同的区间。在 ZoneRules 这个类中包含了 40 个这样的实例。
ZoneId romeZone = ZoneId.of("Europe/Rome");

12.3.3 使用别的日历系统

LocalDate date = LocalDate.of(2014, Month.MARCH, 18); 
JapaneseDate japaneseDate = JapaneseDate.from(date);

12.4 小结

  • Java 8 之前老版的 java.util.Date 类以及其他用于建模日期和时间的类有很多不一致及设计上的缺陷,包括易变性以及糟糕的偏移值、默认值和命名。
  • 新版的日期和时间 API 中,日期–时间对象是不可变的。
  • 新的 API 提供了两种不同的时间表示方式,有效地区分了运行时人和机器的不同需求。
  • 你可以用绝对或者相对的方式操纵日期和时间,操作的结果总是返回一个新的实例,老的日期–时间对象不会发生变化。
  • TemporalAdjuster 让你能够用更精细的方式操纵日期,不再局限于一次只能改变它的一个值,并且你还可按照需求定义自己的日期转换器。
  • 你现在可以按照特定的格式需求,定义自己的格式器,打印输出或者解析日期–时间对象。这些格式器可以通过模板创建,也可以自己编程创建,并且它们都是线程安全的。
  • 你可以用相对于某个地区/位置的方式,或者以与 UTC/格林尼治时间的绝对偏差的方式表示时区,并将其应用到日期–时间对象上,对其进行本地化。
  • 你现在可以使用不同于 ISO-8601 标准系统的其他日历系统了。

http://www.ppmy.cn/news/49446.html

相关文章

c++学习之类与对象3

目录 成员变量和函数的存储 this指针 this指针的工作原理 this指针的应用 const修饰的成员函数 友元 友元的语法 1.普通全局函数成为类的友元 2.类的某个成员函数作为另一个类的友元 整个类作为另一个类的友元 运算符重载 1 运算符重载的基本概念 2 重载加号运算符…

Medical X-rays Dataset汇总(长期更新)

目录​​​​​​​ ChestX-ray8 ChestX-ray14 VinDr-CXR VinDr-PCXR ChestX-ray8 ChestX-ray8 is a medical imaging dataset which comprises 108,948 frontal-view X-ray images of 32,717 (collected from the year of 1992 to 2015) unique patients with the text-mi…

FPGA基于XDMA实现PCIE X8采集AD7606数据 提供工程源码和QT上位机程序和技术支持

1、前言 PCIE(PCI Express)采用了目前业内流行的点对点串行连接,比起 PCI 以及更早期的计算机总线的共享并行架构,每个设备都有自己的专用连接,不需要向整个总线请求带宽,而且可以把数据传输率提高到一个很…

CSS浮动

CSS结构伪类选择器 结构伪类选择器用于选择文档结构中特定位置的元素,根据元素在其父元素中的相对位置或兄弟关系进行选择。这些选择器使得你能够更灵活地控制页面的样式。 :first-child(常用) 用途:选择元素的第一个子元素。 …

六:内存回收

内存回收: 应用程序通过 malloc 函数申请内存的时候,实际上申请的是虚拟内存,此时并不会分配物理内存。 当应用程序读写了这块虚拟内存,CPU 就会去访问这个虚拟内存, 这时会发现这个虚拟内存没有映射到物理内存&…

【PlumGPT】与PlumGPT开启智能对话之旅

文章目录 一、前言二、PlumGPT介绍篇三、PlumGPT登录篇四、PlumGPT体验篇1、与PlumGPT聊天2、让PlumGPT翻译3、让PlumGPT创作4、请PlumGPT写推荐信5、让PlumGPT展示图片6、让PlumGPT充当百科小助手 五、PlumGPT总结篇 PlumGPT入口体验链接:https://plumgpt.com 一、…

Android 10.0 user模式下解除系统进入recovery功能的限制

1.前言 在10.0的系统rom定制化开发中,系统中recovery模式功能也是很重要的一部分,而在原生系统中,对于debug模式的产品,可以通过电源键和音量+键进入recovery模式, 但是在user模式下的产品,对于通过这种方式,进入recovery模式就受限制了,防止用户无操作为了产品安全等…

测试从未如此简单:接口自动化测试Python脚本实现

目录 摘要 步骤1:安装依赖项 步骤2:编写测试脚本 步骤3:运行测试 结论 摘要 自动化测试是现代软件开发过程中的重要环节。在许多情况下,特别是在web应用程序和移动应用程序中,接口自动化测试是其基础。下面就来介绍一…