技术经验|Java基础之LocalDate类

2023-11-12 20:28:12 浏览数 (2)

1 背景

Java里的日期和时间格式化问题,在JDK8(Java SE Development Kit8,以下使用过程中,均称为JDK1.8或者JDK8)以前有很多问题,例如日期类并不提供国际化,没有时区支持,包分配的也比较混乱。所以在JDK8后进行了大改造,索性在rt.jar中新增了一个time包,这样我们就可以个性化设置日期时间的展示方式了。

目前JDK已经到达了JDK 21(Java Development Kit 21),但是在主流的市场上面,使用JDK8的居多。我们现在已经掌握了不少关于日期和时间的操作技巧,但其实随着时间的不断推移,现实的需求也在不断更新,原先的一些API已经难以满足开发需求了。所以从JDK 8之后,为了满足更多的开发需求,Java给我们增加了不少关于日期时间的新特性,接下来本篇文章就带各位来看看这些新特性有哪些。

2 Time包的位置

2.1 Time包在架构中位置

从官网上面的介绍,我们可以看到,新版本的JDK8包括两个实现Java平台标准版(JavaSE)8的产品:JavaSE开发工具包(JDK)8和JavaSE运行时环境(JRE)8。其中JDK8包含了JRE8的所有内容,官网按级别对Java组件技术进行了分类。下面从上到下列出了这些级别,以及每个级别的技术。属于较低级别的技术是属于较高级别的技术的基础。从图中可以看到,Time包所在目录为基础库中的Date and Time文件夹下。

JDK架构JDK架构

2.2 Time包在实际开发中的位置

Time API是一组对日期和时间的最重要方面进行建模的包。java. time包中的核心类使用ISO-8601中定义的日历系统(基于公历系统)作为默认日历。当我们引入JDK8后,可以在rt.jar中的java.time目录下找到对应的基础API,打开可以看到有很多新引入的包和类。功能虽多,但是常用的也就是那么几个,所以你想要尽快熟悉,可以自行点击进去查阅。

2.3 Time下主要基础类

从代码API中,我么可以看到有很多类API,大体分为如下功能点:

  • 本地日期和时间类:LocalDate,LocalDateTime,LocalTime;
  • 带时区的日期和时间类:ZonedDateTime;
  • 时钟、时刻类:Clock、Instant;
  • 时区:ZoneId,ZoneOffset;
  • 某个时期、时间间隔:Period、Duration。

此外,API还提供了两个枚举类:DayOfWeek和Week。今天主要想说说LocalDate这个类。

3 本地日期和时间类

3.1 LocalDate自带功能

API说明,LocalDate自己的方法或功能没有多少,多数都是实现了Temporal, TemporalAdjuster, ChronoLocalDate这三个类。

测试代码如下:

代码语言:javascript复制
public static void main(String[] args) {

        System.out.println("-- LocalDate自带API功能");
        // 当前日期
        System.out.println("LocalDate.now() = "   LocalDate.now());
        // 衍生出来两个方法,其中一个是从时区获取当前日期,另外一个是从从时钟方式获取
        System.out.println("LocalDate.now(ZoneId.of('Asia/Shanghai')) = "   LocalDate.now(ZoneId.of("Asia/Shanghai")));

        // 获取一个设定日期
        System.out.println("LocalDate.of(2023,11, 12) = "   LocalDate.of(2023, 11, 12));
        // 根据参数设置日期,参数分别为年,月,日
        System.out.println("LocalDate.of(2023, Month.of(9), 30) = "   LocalDate.of(2023, Month.of(9), 30)); // 此处设置会有问题,如果你看到请测试

        // 年,一年中的第几天
        System.out.println("LocalDate.ofYearDay(2023, 316) = "   LocalDate.ofYearDay(2023, 316));
        System.out.println("LocalDate.parse("2023-11-12") = "   LocalDate.parse("2023-11-12"));
}

打印结果如下:

3.2 LocalDate继承、重写功能

API方法

说明

是否常用

getDayOfMonth()

获取当前日期是所在月的第几天

getDayOfWeek().getValue()

获取当前日期是星期几(星期的英文全称)

getDayOfYear()

获取当前日期是所在年的第几天

getMonth()

获取当前日期所在月份(月份的英文全称)

getMonthValue()

获取当前日期所在月份的数值

lengthOfMonth()

获取当前日期所在月份有多少天,返回int

lengthOfYear()

获取当前日期所在年有多少天,返回int

isLeapYear()

获取当前日期所在年是否是闰年,返回boolean

with(TemporalAdjusters.firstDayOfMonth())

获取当前日期的第1天

with(TemporalAdjusters.lastDayOfMonth())

获取当前日期月份的最后一天

withDayOfMonth(int dayOfMonth)

将参数中的"日"替换localDate中的"日"

withDayOfYear(int dayOfYear)

将参数中的天数替换localDate中的天数

withMonth(int month)

将参数中的"月"替换localDate中的"月"

withYear(int year)

将参数中的"年"替换localDate中的"年"

minusDays(long days)

将当前日期减几天,一般用于工具类计算中

minusWeeks(long weeks)

将当前日期减几周,一般用于工具类计算中

minusMonths(long months)

将当前日期减几月

minusYears(long years)

将当前日期减几年

plusDays(long days)

将当前日期加几天,一般用于工具类计算中

plusWeeks(long weeks)

将当前日期加几周,一般用于工具类计算中

plusMonths(long months)

将当前日期加几月

plusYears(long years)

将当前日期加一年

代码如下:

代码语言:javascript复制
    public static void main(String[] args) {
        System.out.println("-- LocalDate继承重写API功能");
        // getDayOfXXX函数,获取当前日期的星期(英文)、当前日期所在月份中的第几天、当前日期所在年份中的第几天
        System.out.println("LocalDate.now().getDayOfWeek() = "   LocalDate.now().getDayOfWeek());
        System.out.println("LocalDate.now().getDayOfMonth() = "   LocalDate.now().getDayOfMonth());
        System.out.println("LocalDate.now().getDayOfYear() = "   LocalDate.now().getDayOfYear());

        // lengthXXX函数,获取长度,主要是月有多少天、年有多少天
        System.out.println("LocalDate.now().lengthOfMonth() = "   LocalDate.now().lengthOfMonth());
        System.out.println("LocalDate.now().lengthOfYear() = "   LocalDate.now().lengthOfYear());

        // withXXX函数
        // 返回当前月、周、年的星期几。例如返回当前月的第一天、返回本周的星期二、星期三的日期
        System.out.println("LocalDate.now().with(ChronoField.DAY_OF_MONTH, 1)) = "   LocalDate.now().with(ChronoField.DAY_OF_MONTH, 1));
        System.out.println("LocalDate.now().with(ChronoField.DAY_OF_WEEK, 2) = "   LocalDate.now().with(ChronoField.DAY_OF_WEEK, 2));
        System.out.println("LocalDate.now().with(ChronoField.DAY_OF_WEEK, 3) = "   LocalDate.now().with(ChronoField.DAY_OF_WEEK, 3));
        // 主要是月份的设置,例如设置10月份,那么就返回当前日期的副本且只修改月份
        System.out.println("LocalDate.now().withMonth(10) = "   LocalDate.now().withMonth(10));

        // isXXX函数
        // 当前日期是否在指定日期之前/之后
        System.out.println("LocalDate.now().isBefore(LocalDate.now().minusDays(1)) = "   LocalDate.now().isBefore(LocalDate.now().minusDays(1)));
        System.out.println("LocalDate.now().isAfter(LocalDate.now().minusDays(1)) = "   LocalDate.now().isAfter(LocalDate.now().minusDays(1)));
        // 是否是闰年
        System.out.println("LocalDate.now().isLeapYear() = "   LocalDate.now().isLeapYear());

        // 日期加减,主要有两种类型:第一种是直接进行加减、使用TemporalAmount参数设定;第二种就是直接设定具体的参数
        // 方式一 在当前日期增加3个周期,周期单位为天
        System.out.println("LocalDate.now().plus(Period.ofDays(3)) = "   LocalDate.now().plus(Period.ofDays(3)));
        // 方式二 在当前日期增加4天,在当前日期减少2周
        System.out.println("LocalDate.now().plusDays(3) = "   LocalDate.now().plusDays(4));
        System.out.println("LocalDate.now().minusWeeks(2) = "   LocalDate.now().minusWeeks(2));
    }

打印结果如下:

4 总结

在JDK8之前我们都是使用Date或者Calendar来做计算或者转换,自从有了JDK8,我们的CVX速度很明显增强了。JDK8引入了许多新的特性和改进,使得代码编写更加简洁、可读性更高,并且提供了更好的性能和并发处理能力。

我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!

0 人点赞