JDK8新特性之日期时间API

简介: JDK8新特性之日期时间API-案例实操

一.JDK8新特性之日期时间API-案例实操

之前我们学习了Stream流、Lambda表达式以及方法引用等相关的内容,如果想学习的同学可以看一下之前的文章,接下来我们一起学习一下关于JDK8中新日期时间API的使用。

image.png

二.JDK中原始日期时间存在的问题

  1. 设计不合理,没有一个统一衡量的标准,在java.util和java.sql的包各自中都有日期类。
  2. 非线程安全,所有的日期类都是可变的。
  3. 不提供时区支持。

三. JDK8新特性之新日期时间API

JDK 8中全新的日期时间API,是线程安全的。新的日期及时间API位于 java.time 包中,以下是关于日期时间关键类API。

  • LocalDate :表示日期,包含年月日,格式为 2019-10-16
  • LocalTime :表示时间,包含时分秒,格式为 16:38:54.158549300
  • LocalDateTime :表示日期时间,包含年月日,时分秒,格式为 2018-09-06T15:33:56.750
  • DateTimeFormatter :日期时间格式化类。
  • Instant:时间戳,表示一个特定的时间瞬间。
  • Duration:用于计算2个时间(LocalTime,时分秒)的距离
  • Period:用于计算2个日期(LocalDate,年月日)的距离
  • ZonedDateTime :包含时区的时间

Java中使用的历法是ISO 8601日历系统,它是世界民用历法,也就是我们所说的公历。平年有365天,闰年是366
天。此外Java 8还提供了4套其他历法,分别是:

  • ThaiBuddhistDate:泰国佛教历
  • MinguoDate:中华民国历
  • JapaneseDate:日本历
  • HijrahDate:伊斯兰历

3.1 日期时间的常见操作以及案例实操

3.1.1 LocalDate创建指定的日期

案例代码

import java.time.LocalDate;

public class Demo {
   
   

    public static void main(String[] args) {
   
   
        // 创建指定的日期
        LocalDate date = LocalDate.of(2023, 2, 26);
        System.out.println("创建指定的日期为 "+date);

        // 得到当前的日期
        LocalDate now = LocalDate.now();
        System.out.println("当前的时间为  "+now);

        // 根据LocalDate对象获取对应的日期信息
        System.out.println("年:" + now.getYear());
        System.out.println("月:" + now.getMonth().getValue());
        System.out.println("日:" + now.getDayOfMonth());
        System.out.println("星期:" + now.getDayOfWeek().getValue());
    }
}

3.1.2 LocalTime创建指定的时间

案例代码

import java.time.LocalTime;

public class Demo {
   
   

    public static void main(String[] args) {
   
   
        // 指定的时间
        LocalTime time = LocalTime.of(6,6,6,666);
        System.out.println("设置指定的时间为"+time);

        // 获取当前的时间
        LocalTime nowtime = LocalTime.now();
        System.out.println("获取当前的时间"+nowtime);
        // 获取时间信息:小时、分钟、秒、纳秒等相关的信息
        System.out.println(nowtime.getHour());
        System.out.println(nowtime.getMinute());
        System.out.println(nowtime.getSecond());
        System.out.println(nowtime.getNano());
    }
}

3.1.1 LocalDateTime创建指定的日期和时间

就是之前日期类和时间类的增强版本
案例代码

import java.time.LocalDateTime;

public class Demo {
   
   

    public static void main(String[] args) {
   
   
        // 设置指定的日期时间
        LocalDateTime dateTime = LocalDateTime.of(2023
                        , 9
                        , 01
                        , 9
                        , 10
                        , 10
                        , 910);
        System.out.println("设置指定日期的时间为:"+dateTime);
        // 获取当前的日期时间
        LocalDateTime nowTime = LocalDateTime.now();
        System.out.println("获取当前的日期时间:"+nowTime);
        // 获取日期时间信息
        System.out.println(nowTime.getYear());
        System.out.println(nowTime.getMonth().getValue());
        System.out.println(nowTime.getDayOfMonth());
        System.out.println(nowTime.getDayOfWeek().getValue());
        System.out.println(nowTime.getHour());
        System.out.println(nowTime.getMinute());
        System.out.println(nowTime.getSecond());
        System.out.println(nowTime.getNano());
    }
}

3.2 日期时间的修改和比较

3.2.1 原来的时间上设置新时间,并不会修改原来时间的相关信息

修改日期时间 对日期时间的修改,对已存在的LocalDate对象,新创建了对象,相当于拷贝了原来的时间对象,它并不会修改原来的信息。

案例代码

import java.time.LocalDateTime;

public class Demo {
   
   

    public static void main(String[] args) {
   
   
        LocalDateTime now = LocalDateTime.now();
        System.out.println("现在的时间: "+now);
        // 设置时间为1998 注意:此时获得是另一个对象相关的时间,原来的时间并没有改变
        LocalDateTime localDateTime = now.withYear(1998);
        System.out.println("还是现在的时间,并没有改变:"+now);
        System.out.println("修改后的时间" + localDateTime);
    }
}

3.2.2 日期时间的设置与修改

案例代码

import java.time.LocalDateTime;

public class Demo {
   
   

    public static void main(String[] args) {
   
   
        LocalDateTime now = LocalDateTime.now();
        System.out.println("现在的时间: "+now);
        // 设置时间为1998 注意:此时获得是另一个对象相关的时间,原来的时间并没有改变
        LocalDateTime localDateTime = now.withYear(2001);
        System.out.println("还是现在的时间,并没有改变:"+now);
        System.out.println("修改后的时间" + localDateTime);


        // 在当前日期时间的基础上 加上或者减去指定的时间
        System.out.println("5年后:"+now.plusYears(5));
        System.out.println("5月后:"+now.plusMonths(5));
        System.out.println("5天后:"+now.plusDays(5));
        System.out.println("5年前:"+now.minusYears(5));
        System.out.println("5月前:"+now.minusMonths(5));
        System.out.println("5天前:"+now.minusDays(5));
    }
}

3.2.3 日期时间的比较

在JDK8中日期的比较的相关API方法:isAfter 、isBefore、 isEqual
实现案例

import java.time.LocalDateTime;

public class Demo {
   
   

    public static void main(String[] args) {
   
   
        LocalDateTime before = LocalDateTime.of(2022,2,3,5,4,2,123);
        LocalDateTime now = LocalDateTime.now();
        System.out.println(now.isAfter(before));
        System.out.println(now.isBefore(before));
        System.out.println(now.isEqual(before));
    }
}

3.3 格式化和解析操作

在JDK8中我们可以通过java.time.format.DateTimeFormatter类可以进行日期的解析和格式化操作

案例代码

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class Demo {
   
   

    public static void main(String[] args) {
   
   
        LocalDateTime now = LocalDateTime.now();
        // DateTimeFormatters时间格式化类来指定时间被格式化的格式
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String format = now.format(dateTimeFormatter);
        System.out.println("格式化后的时间为:" + format);

    }
}

3.4 Instant类

在JDK8中给我们新增一个Instant类(时间戳/时间线),内部保存了从1970年1月1日 00:00:00以来的秒和纳秒

案例如下:

import java.time.Instant;

public class Demo {
   
   

    public static void main(String[] args) throws InterruptedException {
   
   
        // 获取从1970年一月一日 00:00:00 到现在的 纳秒
        System.out.println(Instant.now().getNano());
    }
}

3.5 计算日期时间差

3.5.1 Period:用来计算两个日期差(LocalDate)

案例代码


import java.time.LocalDate;
import java.time.Period;

public class Demo {
   
   

    public static void main(String[] args) throws InterruptedException {
   
   
        // 计算日期差
        LocalDate nowDate = LocalDate.now();
        LocalDate date = LocalDate.of(2020, 2, 5);
        Period period = Period.between(date, nowDate);
        System.out.println(period.getYears());
        System.out.println(period.getMonths());
        System.out.println(period.getDays());
    }
}

3.5.2 Duration:用来计算两个时间差(LocalTime)

案例代码如下:

import java.time.Duration;
import java.time.LocalTime;

public class Demo {
   
   

    public static void main(String[] args) throws InterruptedException {
   
   
        // 计算时间差
        LocalTime now = LocalTime.now();
        LocalTime time = LocalTime.of(18, 2, 14);
        // 通过Duration来计算时间差
        Duration duration = Duration.between(now, time);
        System.out.println(duration.toDays());
        System.out.println(duration.toHours());
        System.out.println(duration.toMinutes());
        System.out.println(duration.toMillis());
    }
}

3.6 时间校正器(时钟)

有时候我们想要时间校正器设置为这个月第几周的第几天,获取其它的日期,我们可以设置时间和日期。这时我们通过时间校正器效果会更好。

3.6.1 TemporalAdjuster:自定义时间校正器

案例代码

import java.time.LocalDateTime;
import java.time.temporal.TemporalAdjuster;

public class Demo {
   
   

    public static void main(String[] args) throws InterruptedException {
   
   
        LocalDateTime now = LocalDateTime.now();
        System.out.println(now);
        // 将当前的日期调整到4个月后的第5天
        TemporalAdjuster adJuster = (temporal)->{
   
   
            LocalDateTime dateTime = (LocalDateTime) temporal;
            LocalDateTime nextTime = dateTime.plusMonths(4).withDayOfMonth(5);
            return nextTime;
        };
        LocalDateTime nextTime = now.with(adJuster);
        System.out.println(nextTime);
    }
}

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

TemporalAdjusters提供了许多的方法

import java.time.LocalDateTime;
import java.time.temporal.TemporalAdjusters;

public class Demo {
   
   

    public static void main(String[] args){
   
   
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime nextMonth = now.with(TemporalAdjusters.firstDayOfYear());
        System.out.println("设置为该年的第一天 " + nextMonth);
    }
}

3.7 日期时间的时区

3.7.1 基本知识

Java8 中加入了对时区的支持,LocalDate、LocalTime、LocalDateTime是不带时区的,带时区的日期时间类分别为:ZonedDate、ZonedTime、ZonedDateTime。
其中每个时区都对应着 ID,ID的格式为 “区域/城市” 。例如 :Asia/Shanghai 等。
ZoneId:该类中包含了所有的时区信息

3.7.2 获取所有时区的id

案例代码

public class Demo {
   
   

    public static void main(String[] args){
   
   
        // 获取所有的时区id
        ZoneId.getAvailableZoneIds().forEach(System.out::println);

    }
}

3.7.3 获取指定时区

案例代码

import java.time.Clock;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;

public class Demo {
   
   

    public static void main(String[] args){
   
   

        // 获取标准时间
        ZonedDateTime now1 = ZonedDateTime.now(Clock.systemUTC());
        System.out.println("now1 = " + now1);
        // 获取中国使用的东八区的时区,比标准时间早8个小时
        LocalDateTime now2 = LocalDateTime.now();
        System.out.println("now2 = " + now2);
        // 使用计算机默认的时区,创建日期时间
        ZonedDateTime now3 = ZonedDateTime.now();
        System.out.println("now3 = " + now3);
        // 使用指定的时区创建日期时间
        ZonedDateTime now4 = ZonedDateTime.now(ZoneId.of("Australia/Tasmania"));
        System.out.println("now4 = " + now4);
    }
}

四.JDK8新特性之日期时间API优势:

  1. 新版日期时间API中,日期和时间对象是不可变,操作日期不会影响原来的值,而是生成一个新的实例。
  2. 提供不同的两种方式,有效的区分了人和机器的操作。
  3. TemporalAdjuster可以更精确的操作日期,还可以自定义日期调整期。
  4. 解决了之前日期时间线程不安全的问题。在进行日期时间修改的时候,原来的LocalDate对象是不会被修改,每次操作都是返回了一个新的LocalDate对象,所以在多线程场景下是数据安全的。
相关文章
|
6天前
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
21 4
|
17天前
|
存储 安全 Java
jdk21的外部函数和内存API(MemorySegment)(官方翻译)
本文介绍了JDK 21中引入的外部函数和内存API(MemorySegment),这些API使得Java程序能够更安全、高效地与JVM外部的代码和数据进行互操作,包括调用外部函数、访问外部内存,以及使用不同的Arena竞技场来分配和管理MemorySegment。
15 1
jdk21的外部函数和内存API(MemorySegment)(官方翻译)
|
6天前
|
缓存 JavaScript 前端开发
深入理解 Vue 3 的 Composition API 与新特性
本文详细探讨了 Vue 3 中的 Composition API,包括 setup 函数的使用、响应式数据管理(ref、reactive、toRefs 和 toRef)、侦听器(watch 和 watchEffect)以及计算属性(computed)。我们还介绍了自定义 Hooks 的创建与使用,分析了 Vue 2 与 Vue 3 在响应式系统上的重要区别,并概述了组件生命周期钩子、Fragments、Teleport 和 Suspense 等新特性。通过这些内容,读者将能更深入地理解 Vue 3 的设计理念及其在构建现代前端应用中的优势。
16 0
深入理解 Vue 3 的 Composition API 与新特性
|
1月前
|
存储 JavaScript 前端开发
敲黑板!vue3重点!一文了解Composition API新特性:ref、toRef、toRefs
该文章深入探讨了Vue3中Composition API的关键特性,包括`ref`、`toRef`、`toRefs`的使用方法与场景,以及它们如何帮助开发者更好地管理组件状态和促进逻辑复用。
敲黑板!vue3重点!一文了解Composition API新特性:ref、toRef、toRefs
|
27天前
|
容器
jdk8新特性-详情查看文档
jdk8新特性-详情查看文档
35 3
|
29天前
|
安全 Java API
时间日期API(Date,SimpleDateFormat,Calendar)+java8新增日期API (LocalTime,LocalDate,LocalDateTime)
这篇文章介绍了Java中处理日期和时间的API,包括旧的日期API(Date、SimpleDateFormat、Calendar)和Java 8引入的新日期API(LocalTime、LocalDate、LocalDateTime)。文章详细解释了这些类/接口的方法和用途,并通过代码示例展示了如何使用它们。此外,还讨论了新旧API的区别,新API的不可变性和线程安全性,以及它们提供的操作日期时间的灵活性和简洁性。
|
1月前
|
Java 程序员 API
Java 8新特性之Lambda表达式与Stream API的探索
【9月更文挑战第24天】本文将深入浅出地介绍Java 8中的重要新特性——Lambda表达式和Stream API,通过实例解析其语法、用法及背后的设计哲学。我们将一探究竟,看看这些新特性如何让Java代码变得更加简洁、易读且富有表现力,同时提升程序的性能和开发效率。
|
13天前
|
存储 安全 Java
JDK1.8 新的特性
JDK1.8 新的特性
15 0
|
1月前
|
安全 Java API
【性能与安全的双重飞跃】JDK 22外部函数与内存API:JNI的继任者,引领Java新潮流!
【9月更文挑战第7天】JDK 22外部函数与内存API的发布,标志着Java在性能与安全性方面实现了双重飞跃。作为JNI的继任者,这一新特性不仅简化了Java与本地代码的交互过程,还提升了程序的性能和安全性。我们有理由相信,在外部函数与内存API的引领下,Java将开启一个全新的编程时代,为开发者们带来更加高效、更加安全的编程体验。让我们共同期待Java在未来的辉煌成就!
56 11
|
1月前
|
监控 Java 大数据
【Java内存管理新突破】JDK 22:细粒度内存管理API,精准控制每一块内存!
【9月更文挑战第9天】虽然目前JDK 22的确切内容尚未公布,但我们可以根据Java语言的发展趋势和社区的需求,预测细粒度内存管理API可能成为未来Java内存管理领域的新突破。这套API将为开发者提供前所未有的内存控制能力,助力Java应用在更多领域发挥更大作用。我们期待JDK 22的发布,期待Java语言在内存管理领域的持续创新和发展。