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对象,所以在多线程场景下是数据安全的。
相关文章
|
4月前
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
78 4
|
2月前
|
容器
jdk8新特性-详情查看文档
jdk8新特性-详情查看文档
65 7
|
2月前
|
存储 Java 数据挖掘
Java 8 新特性之 Stream API:函数式编程风格的数据处理范式
Java 8 引入的 Stream API 提供了一种新的数据处理方式,支持函数式编程风格,能够高效、简洁地处理集合数据,实现过滤、映射、聚合等操作。
102 6
|
3月前
|
安全 Java API
告别SimpleDateFormat:Java 8日期时间API的最佳实践
在Java开发中,处理日期和时间是一个基本而重要的任务。传统的`SimpleDateFormat`类因其简单易用而被广泛采用,但它存在一些潜在的问题,尤其是在多线程环境下。本文将探讨`SimpleDateFormat`的局限性,并介绍Java 8引入的新的日期时间API,以及如何使用这些新工具来避免潜在的风险。
55 5
|
4月前
|
缓存 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 的设计理念及其在构建现代前端应用中的优势。
82 1
深入理解 Vue 3 的 Composition API 与新特性
|
3月前
|
JavaScript 前端开发 API
Vue 3新特性详解:Composition API的威力
【10月更文挑战第25天】Vue 3 引入的 Composition API 是一组用于组织和复用组件逻辑的新 API。相比 Options API,它提供了更灵活的结构,便于逻辑复用和代码组织,特别适合复杂组件。本文将探讨 Composition API 的优势,并通过示例代码展示其基本用法,帮助开发者更好地理解和应用这一强大工具。
59 2
|
4月前
|
存储 安全 Java
jdk21的外部函数和内存API(MemorySegment)(官方翻译)
本文介绍了JDK 21中引入的外部函数和内存API(MemorySegment),这些API使得Java程序能够更安全、高效地与JVM外部的代码和数据进行互操作,包括调用外部函数、访问外部内存,以及使用不同的Arena竞技场来分配和管理MemorySegment。
118 1
jdk21的外部函数和内存API(MemorySegment)(官方翻译)
|
5月前
|
存储 JavaScript 前端开发
敲黑板!vue3重点!一文了解Composition API新特性:ref、toRef、toRefs
该文章深入探讨了Vue3中Composition API的关键特性,包括`ref`、`toRef`、`toRefs`的使用方法与场景,以及它们如何帮助开发者更好地管理组件状态和促进逻辑复用。
敲黑板!vue3重点!一文了解Composition API新特性:ref、toRef、toRefs
|
5月前
|
容器
jdk8新特性-详情查看文档
jdk8新特性-详情查看文档
60 3
|
5月前
|
安全 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的不可变性和线程安全性,以及它们提供的操作日期时间的灵活性和简洁性。

热门文章

最新文章