【Java8新特性】关于Java8中的日期时间API,你需要掌握这些!!

简介:

【Java8新特性】关于Java8中的日期时间API,你需要掌握这些!!

写在前面
Java8之前的日期和时间API,存在一些问题,比如:线程安全的问题,跨年的问题等等。这些问题都在Hava8中的日期和时间API中得到了解决,而且Java8中的日期和时间API更加强大。立志成为架构师的你,必须掌握Java8中的日期和时间API。

本地时间和时间戳
主要方法:

now:静态方法,根据当前时间创建对象
of:静态方法,根据指定日期/时间创建对象
plusDays,plusWeeks,plusMonths,plusYears:向当前LocalDate 对象添加几天、几周、几个月、几年
minusDays,minusWeeks,minusMonths,minusYears:从当前LocalDate 对象减去几天、几周、几个月、几年
plus,minus:添加或减少一个Duration 或Period
withDayOfMonth,withDayOfYear,withMonth,withYear:将月份天数、年份天数、月份、年份修改为指定的值并返回新的LocalDate 对象
getDayOfYear:获得年份天数(1~366)
getDayOfWeek:获得星期几(返回一个DayOfWeek枚举值)
getMonth:获得月份, 返回一个Month 枚举值
getMonthValue:获得月份(1~12)
getYear:获得年份
until:获得两个日期之间的Period 对象,或者指定ChronoUnits 的数字
isBefore,isAfter:比较两个LocalDate
isLeapYear:判断是否是闰年
使用 LocalDate、 LocalTime、 LocalDateTime
LocalDate、 LocalTime、 LocalDateTime 类的实例是不可变的对象,分别表示使用 ISO-8601日历系统的日期、时间、日期和时间。它们提供了简单的日期或时间,并不包含当前的时间信息。也不包含与时区相关的信息。

注: ISO-8601日历系统是国际标准化组织制定的现代公民的日期和时间的表示法

方法 描述 示例
now() 静态方法,根据当前时间创建对象 LocalDate localDate = LocalDate.now(); LocalTime localTime = LocalTime.now(); LocalDateTime localDateTime = LocalDateTime.now();
of() 静态方法,根据指定日期/时间创建 对象 LocalDate localDate = LocalDate.of(2016, 10, 26); LocalTime localTime = LocalTime.of(02, 22, 56); LocalDateTime localDateTime = LocalDateTime.of(2016, 10, 26, 12, 10, 55);
plusDays, plusWeeks, plusMonths, plusYears 向当前 LocalDate 对象添加几天、 几周、 几个月、 几年
minusDays, minusWeeks, minusMonths, minusYears 从当前 LocalDate 对象减去几天、 几周、 几个月、 几年
plus, minus 添加或减少一个 Duration 或 Period
withDayOfMonth, withDayOfYear, withMonth, withYear 将月份天数、 年份天数、 月份、 年 份 修 改 为 指 定 的 值 并 返 回 新 的 LocalDate 对象
getDayOfMonth 获得月份天数(1-31)
getDayOfYear 获得年份天数(1-366)
getDayOfWeek 获得星期几(返回一个 DayOfWeek 枚举值)
getMonth 获得月份, 返回一个 Month 枚举值
getMonthValue 获得月份(1-12)
getYear 获得年份
until 获得两个日期之间的 Period 对象, 或者指定 ChronoUnits 的数字
isBefore, isAfter 比较两个 LocalDate
isLeapYear 判断是否是闰年
示例代码如下所示。

// 获取当前系统时间
LocalDateTime localDateTime1 = LocalDateTime.now();
System.out.println(localDateTime1);
// 运行结果:2019-10-27T13:49:09.483

// 指定日期时间
LocalDateTime localDateTime2 = LocalDateTime.of(2019, 10, 27, 13, 45,10);
System.out.println(localDateTime2);
// 运行结果:2019-10-27T13:45:10

LocalDateTime localDateTime3 = localDateTime1

    // 加三年
    .plusYears(3)
    // 减三个月
    .minusMonths(3);

System.out.println(localDateTime3);
// 运行结果:2022-07-27T13:49:09.483

System.out.println(localDateTime1.getYear()); // 运行结果:2019
System.out.println(localDateTime1.getMonthValue()); // 运行结果:10
System.out.println(localDateTime1.getDayOfMonth()); // 运行结果:27
System.out.println(localDateTime1.getHour()); // 运行结果:13
System.out.println(localDateTime1.getMinute()); // 运行结果:52
System.out.println(localDateTime1.getSecond()); // 运行结果:6

LocalDateTime localDateTime4 = LocalDateTime.now();
System.out.println(localDateTime4); // 2019-10-27T14:19:56.884
LocalDateTime localDateTime5 = localDateTime4.withDayOfMonth(10);
System.out.println(localDateTime5); // 2019-10-10T14:19:56.884
Instant 时间戳
用于“时间戳”的运算。它是以Unix元年(传统的设定为UTC时区1970年1月1日午夜时分)开始所经历的描述进行运算 。

示例代码如下所示。

Instant instant1 = Instant.now(); // 默认获取UTC时区
System.out.println(instant1);
// 运行结果:2019-10-27T05:59:58.221Z

// 偏移量运算
OffsetDateTime offsetDateTime = instant1.atOffset(ZoneOffset.ofHours(8));
System.out.println(offsetDateTime);
// 运行结果:2019-10-27T13:59:58.221+08:00

// 获取时间戳
System.out.println(instant1.toEpochMilli());
// 运行结果:1572156145000

// 以Unix元年为起点,进行偏移量运算
Instant instant2 = Instant.ofEpochSecond(60);
System.out.println(instant2);
// 运行结果:1970-01-01T00:01:00Z
Duration 和 Period
Duration:用于计算两个“时间”间隔。

Period:用于计算两个“日期”间隔 。

Instant instant_1 = Instant.now();
try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}
Instant instant_2 = Instant.now();

Duration duration = Duration.between(instant_1, instant_2);
System.out.println(duration.toMillis());
// 运行结果:1000

LocalTime localTime_1 = LocalTime.now();
try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}
LocalTime localTime_2 = LocalTime.now();

System.out.println(Duration.between(localTime_1, localTime_2).toMillis());
// 运行结果:1000
LocalDate localDate_1 = LocalDate.of(2018,9, 9);
LocalDate localDate_2 = LocalDate.now();

Period period = Period.between(localDate_1, localDate_2);
System.out.println(period.getYears()); // 运行结果:1
System.out.println(period.getMonths()); // 运行结果:1
System.out.println(period.getDays()); // 运行结果:18
日期的操纵
TemporalAdjuster : 时间校正器。有时我们可能需要获取例如:将日期调整到“下个周日”等操作。

TemporalAdjusters : 该类通过静态方法提供了大量的常用 TemporalAdjuster 的实现。

例如获取下个周日,如下所示:

LocalDate nextSunday = LocalDate.now().with(TemporalAdjusters.next(DayOfWeek.SUNDAY));
完整的示例代码如下所示。

LocalDateTime localDateTime1 = LocalDateTime.now();
System.out.println(localDateTime1); // 2019-10-27T14:19:56.884

// 获取这个第一天的日期
System.out.println(localDateTime1.with(TemporalAdjusters.firstDayOfMonth())); // 2019-10-01T14:22:58.574
// 获取下个周末的日期
System.out.println(localDateTime1.with(TemporalAdjusters.next(DayOfWeek.SUNDAY))); // 2019-11-03T14:22:58.574

// 自定义:下一个工作日
LocalDateTime localDateTime2 = localDateTime1.with(l -> {

LocalDateTime localDateTime = (LocalDateTime) l;
DayOfWeek dayOfWeek =  localDateTime.getDayOfWeek();

if (dayOfWeek.equals(DayOfWeek.FRIDAY)) {
   return localDateTime.plusDays(3);
} else if (dayOfWeek.equals(DayOfWeek.SATURDAY)) {
   return localDateTime.plusDays(2);
} else {
   return localDateTime.plusDays(1);
}

});
System.out.println(localDateTime2);
// 运行结果:2019-10-28T14:30:17.400
解析与格式化
java.time.format.DateTimeFormatter 类:该类提供了三种格式化方法:

预定义的标准格式
语言环境相关的格式
自定义的格式
示例代码如下所示。

DateTimeFormatter dateTimeFormatter1 = DateTimeFormatter.ISO_DATE;
LocalDateTime localDateTime = LocalDateTime.now();
String strDate1 = localDateTime.format(dateTimeFormatter1);
System.out.println(strDate1);
// 运行结果:2019-10-27

// Date -> String
DateTimeFormatter dateTimeFormatter2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String strDate2 = dateTimeFormatter2.format(localDateTime);
System.out.println(strDate2);
// 运行结果:2019-10-27 14:36:11

// String -> Date
LocalDateTime localDateTime1 = localDateTime.parse(strDate2, dateTimeFormatter2);
System.out.println(localDateTime1);
// 运行结果:2019-10-27T14:37:39
时区的处理
Java8 中加入了对时区的支持,带时区的时间为分别为:ZonedDate、 ZonedTime、 ZonedDateTime。

其中每个时区都对应着 ID,地区ID都为 “{区域}/{城市}”的格式,例如 : Asia/Shanghai 等。

ZoneId:该类中包含了所有的时区信息
getAvailableZoneIds() : 可以获取所有时区时区信息
of(id) : 用指定的时区信息获取 ZoneId 对象
示例代码如下所示。

// 获取所有的时区
Set set = ZoneId.getAvailableZoneIds();
System.out.println(set);

// 通过时区构建LocalDateTime
LocalDateTime localDateTime1 = LocalDateTime.now(ZoneId.of("America/El_Salvador"));
System.out.println(localDateTime1);
// 2019-10-27T00:46:21.268

// 以时区格式显示时间
LocalDateTime localDateTime2 = LocalDateTime.now();
ZonedDateTime zonedDateTime1 = localDateTime2.atZone(ZoneId.of("Africa/Nairobi"));
System.out.println(zonedDateTime1);
// 2019-10-27T14:46:21.273+03:00[Africa/Nairobi]
与传统日期处理的转换

写在最后
如果觉得文章对你有点帮助,请微信搜索并关注「 冰河技术 」微信公众号,跟冰河学习Java8新特性。

最后,附上Java8新特性核心知识图,祝大家在学习Java8新特性时少走弯路。

原文地址https://www.cnblogs.com/binghe001/p/13028868.html

相关文章
|
8天前
|
Java API C++
Java 8 Stream Api 中的 peek 操作
本文介绍了Java中`Stream`的`peek`操作,该操作通过`Consumer<T>`函数消费流中的每个元素,但不改变元素类型。文章详细解释了`Consumer<T>`接口及其使用场景,并通过示例代码展示了`peek`操作的应用。此外,还对比了`peek`与`map`的区别,帮助读者更好地理解这两种操作的不同用途。作者为码农小胖哥,原文发布于稀土掘金。
Java 8 Stream Api 中的 peek 操作
|
10天前
|
监控 Java 大数据
【Java内存管理新突破】JDK 22:细粒度内存管理API,精准控制每一块内存!
【9月更文挑战第9天】虽然目前JDK 22的确切内容尚未公布,但我们可以根据Java语言的发展趋势和社区的需求,预测细粒度内存管理API可能成为未来Java内存管理领域的新突破。这套API将为开发者提供前所未有的内存控制能力,助力Java应用在更多领域发挥更大作用。我们期待JDK 22的发布,期待Java语言在内存管理领域的持续创新和发展。
|
12天前
|
Java API 数据处理
【Java的SIMD革命】JDK 22向量API:释放硬件潜能,让Java应用性能飙升!
【9月更文挑战第7天】 JDK 22向量API的发布标志着Java编程语言在SIMD技术领域的重大突破。这一新特性不仅释放了现代硬件的潜能,更让Java应用性能实现了飙升。我们有理由相信,在未来的发展中,Java将继续引领编程语言的潮流,为开发者们带来更加高效、更加强大的编程体验。让我们共同期待Java在SIMD技术的推动下开启一个全新的性能提升时代!
|
13天前
|
Java API 开发者
【Java字节码操控新篇章】JDK 22类文件API预览:解锁Java底层的无限可能!
【9月更文挑战第6天】JDK 22的类文件API为Java开发者们打开了一扇通往Java底层世界的大门。通过这个API,我们可以更加深入地理解Java程序的工作原理,实现更加灵活和强大的功能。虽然目前它还处于预览版阶段,但我们已经可以预见其在未来Java开发中的重要地位。让我们共同期待Java字节码操控新篇章的到来!
|
11天前
|
Java API 开发者
【Java字节码的掌控者】JDK 22类文件API:解锁Java深层次的奥秘,赋能开发者无限可能!
【9月更文挑战第8天】JDK 22类文件API的引入,为Java开发者们打开了一扇通往Java字节码操控新世界的大门。通过这个API,我们可以更加深入地理解Java程序的底层行为,实现更加高效、可靠和创新的Java应用。虽然目前它还处于预览版阶段,但我们已经可以预见其在未来Java开发中的重要地位。让我们共同期待Java字节码操控新篇章的到来,并积极探索类文件API带来的无限可能!
|
1月前
|
机器人 API Python
智能对话机器人(通义版)会话接口API使用Quick Start
本文主要演示了如何使用python脚本快速调用智能对话机器人API接口,在参数获取的部分给出了具体的获取位置截图,这部分容易出错,第一次使用务必仔细参考接入参数获取的位置。
|
20天前
|
存储 JSON API
淘系API接口(解析返回的json数据)商品详情数据解析助力开发者
——在成长的路上,我们都是同行者。这篇关于商品详情API接口的文章,希望能帮助到您。期待与您继续分享更多API接口的知识,请记得关注Anzexi58哦! 淘宝API接口(如淘宝开放平台提供的API)允许开发者获取淘宝商品的各种信息,包括商品详情。然而,需要注意的是,直接访问淘宝的商品数据API通常需要商家身份或开发者权限,并且需要遵循淘宝的API使用协议。
淘系API接口(解析返回的json数据)商品详情数据解析助力开发者
|
30天前
|
SQL 存储 数据处理
|
1月前
|
XML JSON API
RESTful API设计最佳实践:构建高效、可扩展的接口
【8月更文挑战第17天】RESTful API设计是一个涉及多方面因素的复杂过程。通过遵循上述最佳实践,开发者可以构建出更加高效、可扩展、易于维护的API。然而,值得注意的是,最佳实践并非一成不变,随着技术的发展和业务需求的变化,可能需要不断调整和优化API设计。因此,保持对新技术和最佳实践的关注,是成为一名优秀API设计师的关键。
|
1月前
|
监控 API 数据安全/隐私保护
​邮件API触发式接口分析?邮件API接口好评榜
邮件API在企业通信和营销中至关重要,通过自动化邮件发送流程提升效率与客户满意度。本文解析邮件API触发式接口,即基于特定事件(如用户注册、购买产品)自动发送邮件的技术,能显著加快企业响应速度并增强用户体验。推荐市场上的优秀邮件API产品,包括SendGrid、Mailgun、Amazon SES、Postmark及新兴的AOKSend,它们各具特色,如高发送率、详细分析工具、灵活配置、强大的日志功能及用户友好的API接口,帮助企业根据不同需求选择最合适的邮件API解决方案。