首页 > 其他分享 >第十四章 JDK 8新的日期和时间 API

第十四章 JDK 8新的日期和时间 API

时间:2024-11-24 16:58:59浏览次数:11  
标签:JDK System println 日期 API LocalDateTime 第十四章 now out

目录

一、旧版日期时间 API 存在的问题

二、新日期时间 API介绍

三、JDK 8的日期和时间类

四、JDK 8的时间格式化与解析

五、JDK 8的 Instant 类

六、JDK 8的计算日期时间差类

七、JDK 8的时间校正器

八、JDK 8设置日期时间的时区


一、旧版日期时间 API 存在的问题

1. 设计很差: 在java.util和java.sql的包中都有日期类,java.util.Date同时包含日期和时间,而java.sql.Date仅包含日期。此外用于格式化和解析的类在java.text包中定义。

2. 非线程安全:java.util.Date 是非线程安全的,所有的日期类都是可变的,这是Java日期类最大的问题之一。

3. 时区处理麻烦:日期类并不提供国际化,没有时区支持,因此Java引入了java.util.Calendar和

java.util.TimeZone类,但他们同样存在上述所有的问题。

二、新日期时间 API介绍

JDK 8中增加了一套全新的日期时间API,这套API设计合理,是线程安全的。新的日期及时间API位于 java.time 包中,下面是一些关键类。

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:伊斯兰历

三、JDK 8的日期和时间类

LocalDate、LocalTime、LocalDateTime类的实例是不可变的对象,分别表示使用 ISO-8601 日历系统的日期、时间、日期和时间。它们提供了简单的日期或时间,并不包含当前的时间信息,也不包含与时区相关的信息。

import org.junit.Test;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;

public class StreamTest {

    // LocalDate:获取日期时间的信息。格式为 2019-10-16
    @Test
    public void test01() {
        // 创建指定日期
        LocalDate fj = LocalDate.of(1985, 9, 23);
        System.out.println("fj = " + fj); // 1985-09-23
        // 得到当前日期
        LocalDate nowDate = LocalDate.now();
        System.out.println("nowDate = " + nowDate); // 2024-11-19
        // 获取日期信息
        System.out.println("年: " + nowDate.getYear());
        System.out.println("月: " + nowDate.getMonthValue());
        System.out.println("日: " + nowDate.getDayOfMonth());
        System.out.println("星期: " + nowDate.getDayOfWeek());
    }
    // LocalTime类: 获取时间信息。格式为 16:38:54.158549300
    @Test
    public void test02() {
        // 得到指定的时间
        LocalTime time = LocalTime.of(12,15, 28, 129_900_000);
        System.out.println("time = " + time);
        // 得到当前时间
        LocalTime nowTime = LocalTime.now();
        System.out.println("nowTime = " + nowTime);
        // 获取时间信息
        System.out.println("小时: " + nowTime.getHour());
        System.out.println("分钟: " + nowTime.getMinute());
        System.out.println("秒: " + nowTime.getSecond());
        System.out.println("纳秒: " + nowTime.getNano());
    }
    // LocalDateTime类: 获取日期时间信息。格式为 2018-09-06T15:33:56.750
    @Test
    public void test03() {
        LocalDateTime fj = LocalDateTime.of(1985, 9, 23, 9, 10, 20);
        System.out.println("fj = " + fj); // 1985-09-23T09:10:20
        // 得到当前日期时间
        LocalDateTime now = LocalDateTime.now();
        System.out.println("now = " + now); // 2024-11-19T22:33:24.497896800
        System.out.println(now.getYear());
        System.out.println(now.getMonthValue());
        System.out.println(now.getDayOfMonth());
        System.out.println(now.getHour());
        System.out.println(now.getMinute());
        System.out.println(now.getSecond());
        System.out.println(now.getNano());
    }
}

对日期时间的修改,对已存在的LocalDate对象,创建它的修改版,最简单的方式是使用withAttribute方法。withAttribute方法会创建对象的一个副本,并按照需要修改它的属性。以下所有的方法都返回了一个修改属性的对象,他们不会影响原来的对象。

import org.junit.Test;
import java.time.LocalDateTime;

public class StreamTest {

    // LocalDateTime类: 对日期时间的修改
    @Test
    public void test05() {
        LocalDateTime now = LocalDateTime.now();
        System.out.println("now = " + now);
        // 修改日期时间
        LocalDateTime setYear = now.withYear(2078);
        System.out.println("修改年份: " + setYear);
        System.out.println("now == setYear: " + (now == setYear));
        System.out.println("修改月份: " + now.withMonth(6));
        System.out.println("修改小时: " + now.withHour(9));
        System.out.println("修改分钟: " + now.withMinute(11));
        // 再当前对象的基础上加上或减去指定的时间
        LocalDateTime localDateTime = now.plusDays(5);
        System.out.println("5天后: " + localDateTime);
        System.out.println("now == localDateTime: " + (now == localDateTime));
        System.out.println("10年后: " + now.plusYears(10));
        System.out.println("20月后: " + now.plusMonths(20));
        System.out.println("20年前: " + now.minusYears(20));
        System.out.println("5月前: " + now.minusMonths(5));
        System.out.println("100天前: " + now.minusDays(100));
    }
}
日期时间的比较
import org.junit.Test;

import java.time.LocalDate;
import java.time.LocalDateTime;

public class StreamTest {

    // 日期时间的比较
    @Test
    public void test06() {
        // 在JDK8中,LocalDate类中使用isBefore()、isAfter()、equals()方法来比较两个日期,可直接进行比较。
        LocalDate now = LocalDate.now();
        LocalDate date = LocalDate.of(2018, 8, 8);
        System.out.println(now.isBefore(date)); // false
        System.out.println(now.isAfter(date)); // true
    }
}

四、JDK 8的时间格式化与解析

通过 java.time.format.DateTimeFormatter 类可以进行日期时间解析与格式化。

import org.junit.Test;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class StreamTest {

    // 日期格式化
    @Test
    public void test04() {
        // 得到当前日期时间
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        // 将日期时间格式化为字符串
        String format = now.format(formatter);
        System.out.println("format = " + format);
        // 将字符串解析为日期时间
        LocalDateTime parse = LocalDateTime.parse("1985-09-23 10:12:22", formatter);
        System.out.println("parse = " + parse);
        LocalDateTime time = LocalDateTime.of(2024, 11, 19, 20, 40, 14);
        System.out.println(time.format(formatter));
    }
}

五、JDK 8 Instant

Instant 时间戳/时间线,内部保存了从1970年1月1日 00:00:00以来的秒和纳秒。

import org.junit.Test;
import java.time.Instant;

public class StreamTest {

    // 时间戳
    @Test
    public void test07() {
        Instant now = Instant.now();
        System.out.println("当前时间戳 = " + now);
        // 获取从1970年1月1日 00:00:00的秒
        System.out.println(now.getNano()); // 纳秒
        System.out.println(now.getEpochSecond());
        System.out.println(now.toEpochMilli());
        System.out.println(System.currentTimeMillis());
        Instant instant = Instant.ofEpochSecond(5);
        System.out.println(instant);
    }
}


六、JDK 8的计算日期时间差类

Duration/Period类: 计算日期时间差。

1. Duration:用于计算2个时间(LocalTime,时分秒)的距离

2. Period:用于计算2个日期(LocalDate,年月日)的距离

import org.junit.Test;
import java.time.*;
import java.time.temporal.ChronoUnit;

public class StreamTest {

    // Duration/Period类: 计算日期时间差
    @Test
    public void test08() {
        // Duration计算时间的距离
        LocalTime now = LocalTime.now();
        LocalTime time = LocalTime.of(14, 15, 20);
        Duration duration = Duration.between(time, now);
        System.out.println("相差的天数:" + duration.toDays());
        System.out.println("相差的小时数:" + duration.toHours());
        System.out.println("相差的分钟数:" + duration.toMinutes());
        System.out.println("相差的秒数:" + duration.toSeconds());
        // Period计算日期的距离
        LocalDate nowDate = LocalDate.now();
        LocalDate date = LocalDate.of(1998, 8, 8);
        // 让后面的时间减去前面的时间
        Period period = Period.between(date, nowDate);
        System.out.println("相差的年:" + period.getYears());
        System.out.println("相差的月:" + period.getMonths());
        System.out.println("相差的天:" + period.getDays());

        LocalDateTime nowDateTime = LocalDateTime.now();
        LocalDateTime dateTime = LocalDateTime.of(2012, 10, 10, 9, 9, 10);
        // 计算当前时间与特定日期时间的距离
        // 如果你需要计算小时、分钟或秒等其他时间单位的距离,可以更换ChronoUnit中的相应枚举值。
        long distance = ChronoUnit.DAYS.between(nowDateTime, dateTime);
        System.out.println(distance);
    }
}

七、JDK 8的时间校正器

有时我们可能需要获取例如:将日期调整到“下一个月的第一天”等操作。可以通过时间校正器来进行。

  • TemporalAdjuster : 时间校正器。

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

import org.junit.Test;
import java.time.*;
import java.time.temporal.TemporalAdjuster;

public class StreamTest {

    // TemporalAdjuster类:自定义调整时间
    @Test
    public void test09() {
        LocalDateTime now = LocalDateTime.now();
        // 得到下一个月的第一天
        TemporalAdjuster firsWeekDayOfNextMonth = temporal -> {
            LocalDateTime dateTime = (LocalDateTime) temporal;
            LocalDateTime nextMonth = dateTime.plusMonths(1).withDayOfMonth(1);
            System.out.println("nextMonth = " + nextMonth);
            return nextMonth;
        };
        LocalDateTime nextMonth = now.with(firsWeekDayOfNextMonth);
        System.out.println("nextMonth = " + nextMonth);
    }
}


八、JDK 8设置日期时间的时区

Java8 中加入了对时区的支持,LocalDate、LocalTime、LocalDateTime是不带时区的,带时区的日期时间类分别为:ZonedDate、ZonedTime、ZonedDateTime。

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

ZoneId:该类中包含了所有的时区信息。

import org.junit.Test;
import java.time.*;

public class StreamTest {

    // 设置日期时间的时区
    @Test
    public void test10() {
        // 1.获取所有的时区ID
        // ZoneId.getAvailableZoneIds().forEach(System.out::println);
        // 不带时间,获取计算机的当前时间
        LocalDateTime now = LocalDateTime.now(); // 中国使用的东八区的时区.比标准时间早8个小时
        System.out.println("now = " + now);
        // 2.操作带时区的类
        // now(Clock.systemUTC()): 创建世界标准时间
        ZonedDateTime bz = ZonedDateTime.now(Clock.systemUTC());
        System.out.println("bz = " + bz);
        // now(): 使用计算机的默认的时区,创建日期时间
        ZonedDateTime now1 = ZonedDateTime.now();
        System.out.println("now1 = " + now1); // 2019-10-19T16:19:44.007153500+08:00[Asia/Shanghai]
        // 使用指定的时区创建日期时间
        ZonedDateTime now2 = ZonedDateTime.now(ZoneId.of("America/Vancouver"));
        System.out.println("now2 = " + now2); // 2019-10-19T01:21:44.248794200-07:00[America/Vancouver]
    }
}


标签:JDK,System,println,日期,API,LocalDateTime,第十四章,now,out
From: https://blog.csdn.net/qushaming/article/details/143896845

相关文章

  • Windows 的复制和粘贴功能是基于 文件系统操作(如 CopyFile 或 MoveFile API)来实现的,而
    在Windows操作系统中,复制粘贴功能和robocopy(RobustFileCopy)技术的使用场景和目标不同,这也是为什么微软在日常用户界面中选择使用传统的复制粘贴(Copy-Paste)功能,而不是直接依赖robocopy技术的原因。下面我将从几个关键角度进行详细分析。1. 目标用户与应用场景不同复制粘......
  • Vue 3组件间通信全解:选项式API vs 组合式API
    在Vue3中,组件间通信的方式可以分为两大类:选项式API(OptionsAPI)和组合式API(CompositionAPI)。每种API风格都有其特点和适用场景,下面将分别介绍这两种API风格下的组件间通信方法。选项式API(OptionsAPI)1.props与emitprops用于父组件向子组件传递数据,而emit用于子组件向父......
  • k8s阶段03 持久卷, PV和PVC, CSI存储方案示例csi-driver-nfs, OpenEBS, ConfigMap, Se
    2持久卷PV和PVC在Pod级别定义存储卷有两个弊端卷对象的生命周期无法独立于Pod而存在用户必须要足够熟悉可用的存储及其详情才能在Pod上配置和使用卷PV和PVC可用于降低这种耦合关系PV(PersistentVolume)是集群级别的资源,负责将存储空间引入到集群中,通常由管理员定义......
  • 深入理解JDBC API:从SQL注入到PreparedStatement的安全解决方案
    深入理解JDBCAPI:从SQL注入到PreparedStatement的安全解决方案引言在现代Web应用开发中,数据库操作是不可或缺的一部分。Java数据库连接(JDBC)API为Java开发者提供了一种与数据库交互的标准方式。然而,随着应用的复杂性增加,安全问题也随之而来。其中,SQL注入是最常见且危险的安全漏洞......
  • 使用 JavaScript 的 XMLHttpRequest 或 Fetch API 发送 HTTP 请求时,GET 请求和 POST
    使用JavaScript的XMLHttpRequest或FetchAPI发送HTTP请求时,GET请求和POST请求处理参数的方式不同,这与HTTP协议的设计有关GET请求的参数特点:GET请求的参数通过URL传递。原因:URL表现方式:GET请求的主要目的是从服务器获取资源。URL是资源的唯一标识,因此GET......
  • 学会这些 API,轻松开发 UniApp 音视频功能
    UniApp音频与视频处理详解UniApp提供了一系列强大的API,用于音频与视频的录制、播放和管理。这些API能够帮助开发者快速实现多媒体功能,适用于聊天工具、音乐播放器、短视频应用等场景。本文详细介绍音频与视频相关API的作用、参数及示例代码。一、音频处理1.录音功能(Re......
  • 同花顺API有哪些技术指标查询接口?
    Python股票接口实现查询账户,提交订单,自动交易(1)Python股票程序交易接口查账,提交订单,自动交易(2)股票量化,Python炒股,CSDN交流社区>>>同花顺API的基本概念同花顺API是为开发者提供的一种工具接口。它旨在让开发者能够与同花顺的金融数据资源进行交互。这个API涵盖了众多功......
  • 随机图片API自建分享
     特点支持模式:横屏、竖屏、自适应三种模式。图片格式:高分辨率AVIF图片5000张,部分图片使用超分辨率处理。稳定性:支持三网线路(电信、联通、移动),可手动选择线路优化加载速API端点1.随机横屏图片分辨率:4K-10KGEThttps://api.rls.icu/horizontalGEThttps://api.rls.icu/......
  • JDBC API详解:从注册驱动到执行SQL语句
    JDBCAPI详解:从注册驱动到执行SQL语句在Java中,JDBC(JavaDatabaseConnectivity)是用于连接和操作数据库的标准API。本文将详细介绍如何使用JDBCAPI从注册驱动到执行SQL语句的完整流程,包括注册驱动、获取连接、定义SQL语句、获取执行SQL语句的对象、执行SQL语句、处理返回结果以及......
  • Flink普通API之Source使用全解析
    Flink普通API之Source使用全解析一、引言在Flink的流式计算世界里,Source作为数据的源头起着至关重要的作用。它能够为Flink任务提供数据输入,无论是批处理还是流处理场景,合适的Source选择与使用都能让数据处理流程顺利开启。本文将深入探讨Flink中Source的相关知识,包括预定......