美文网首页
JDK新特性(六)LocalDate日期函数的使用

JDK新特性(六)LocalDate日期函数的使用

作者: moutory | 来源:发表于2022-04-13 21:43 被阅读0次

    前言

    相比于大多数方法已经过时的Date类(java.util),使用JDK8推出的LocalDate系列的日期(以及时间)格式的工具类已经是大多数项目的选择。本篇文章将对LocalDate类的常用API以及这个日期类和Date类的区别进行介绍。希望本篇文章对各位读者能够有所帮助。

    一、LocalDate类的简介

    在JDK1.8中,新推出了LocalDate、LocatTime、LocalDateTime这三个日期时间相关的工具类,这三者分别涵盖了日期、时间、日期时间三个场景的信息,我们可以在实际应用中选择符合需要的类来进行使用。比如我想知道明天是几号,那很明显LocalDate就可以满足我的需要。

    二、常见API使用

    (一)对象初始化
    名称 作用
    now() 获取包含默认时区的系统时钟的当前日期
    now(Clock clock) 提供LocalDate实例,该实例具有从指定时钟获得的当前日期
    now(ZoneId zone) 给出当前日期的LocalDate实例,该日期来自指定时区的系统时钟
    of(int year, int month, int dayOfMonth) 从给定的年、月、日中获得LocalDate实例,输入数据类型为int
        @Test
        public void LocalDateTest(){
            System.out.println(LocalDate.now());
            // now 方法可以获取指定时区的日期
            System.out.println(LocalDate.now(Clock.systemUTC()));
            System.out.println(LocalDate.now(ZoneId.systemDefault()));
            System.out.println(LocalDate.of(2022,3,3));
        }
    
    代码执行结果
    (二)日期计算
    名称 作用
    plusDays 往后加n天,即获取n天后的日期
    plusWeeks 往后加n周,即获取n周后的日期
    plusMonths 往后加n月,即获取n月后的日期
    plusYears 往后加n年,即获取n年后的日期
    minusDays 往后减n天,即获取n天前的日期
    ... minus也有减周、月、年相关的API这里就不写了
    now 获取当前日期

    需要注意的是,日期计算后会生成新的日期,并不会影响原有的日期对象

        @Test
        public void LocalDateTest(){
            //获取当前的日期
            LocalDate currentDate = LocalDate.now();
            LocalDate after3Date = currentDate.plusDays(3);
            LocalDate after2Week = currentDate.plusWeeks(2);
            LocalDate after1Month = currentDate.plusMonths(1);
            LocalDate after1Year = currentDate.plusYears(1);
            LocalDate before3Date = currentDate.minusDays(3);
            System.out.println("当前的日期为:" + currentDate);
            System.out.println("3天后的日期为:" + after3Date);
            System.out.println("2周后的日期为:" + after2Week);
            System.out.println("1个月的日期为:" + after1Month);
            System.out.println("1年后的日期为:" + after1Year);
            System.out.println("3天前的日期为:" + before3Date);
        }
    
    执行结果图
    (三)日期比较
    名称 作用
    isBefore 判断当前日期对象是否在比较的日期对象之前
    isAfter 判断当前日期对象是否在比较的日期对象之后
    isEqual 判断当前日期对象是否与比较的日期对象(日期)相等
        @Test
        public void LocalDateTest(){
            //获取当前的日期
            LocalDate date1 = LocalDate.now();
            LocalDate date2 = date1.plusDays(3);
            System.out.println("date1 before date2 ? " + date1.isBefore(date2));
            System.out.println("date1 after date2 ? " + date1.isAfter(date2));
            System.out.println("date1 equal date2 ? " + date1.isEqual(date2));
        }
    
    执行结果

    PS:其实这一块的话,java.utls.Date类也有类似的日期比较方法。从API的使用上来说,LocalDate和Date可能没有太大区别。从安全性来说,LocalDate要更胜利一筹。

    (四)日期和字符串转化

    LocalDate提供了丰富的API来满足我们对于不同日期格式的需求,最主要的核心方法就是format()parse(),前者让我们可以实现日期的格式化,后者可以将字符串转为LocalDate对象。

    1、日期的格式化(LocalDate对象转字符串)

    这个方法要求我们提供一个DateTimeFormatter对象来作为格式标准。一般我们会使用DateTimeFormatter对象的静态方法来定义日期格式。

    image.png
        @Test
        public void LocalDateTest(){
            //获取当前的日期
            LocalDate date1 = LocalDate.now();
            String formatDate = date1.format(DateTimeFormatter.ofPattern("MM dd / yyyy"));
            System.out.println("格式化后的日期为:" + formatDate);
        }
    
    执行结果
    2、字符串转日期

    我们一般使用parse()方法来进行字符串转日期的操作,需要注意的是parse()方法默认是按照yyyy-MM-dd的格式来将字符串转换为日期对象的,如果给定的字符串不是这个日期格式的,则需要手动指定解析的日期格式,否则程序会抛异常!!

        @Test
        public void LocalDateTest(){
            // 默认转换的日期格式为 yyyy-MM-dd
            LocalDate date = LocalDate.parse("2022-04-03");
            System.out.println("date解析后的日期为:" + date);
            LocalDate date2 = LocalDate.parse("2022/04/03",DateTimeFormatter.ofPattern("yyyy/MM/dd"));
            System.out.println("date2解析后的日期为:" + date2);
        }
    
    代码执行结果
    (五)获取对象上常用的属性

    我们还可以便捷的在日期对象上面获取年月日等属性,方便后续程序的逻辑判断。常用的API如下:

    名称 作用
    get(TemporalField field) 获取指定字段的int值
    getChronology() 获取该日期格式,例如:ISO
    getDayOfMonth() 获取一个月中的第几号,为int类型
    getDayOfWeek() 获取星期字段,返回DayOfWeek
    getDayOfYear() 以 int 格式获取一年中的第几天。它可以返回从 1 到 365 或 366 (闰年)。
    getEra() 获取在此日期适用的时代。例如:"CE "从第一年开始,"BCE "从零年开始。

    PS:LocalDate这套日期工具类体系中,会把月、日、年都看成是不同的对象,方便我们取出值后做进一步的日期比较或者计算。

        @Test
        public void LocalDateTest(){
            LocalDate currentDate = LocalDate.now();
            System.out.println("年份信息为:" + currentDate.getYear());
            System.out.println("月份信息为:" + currentDate.getMonth().getValue());
            System.out.println("日期信息为:" + currentDate.getDayOfMonth());
            System.out.println("日期格式信息为:" + currentDate.getChronology());
            System.out.println("年份格式信息(get写法)为:" + currentDate.get(ChronoField.YEAR));
        }
    

    上面的API虽然多,但是其实用的多的也就是获取年月日这些信息的API

    代码执行结果
    (六)LocalDateLocalTimeLocalDateTime三者的转换
    1、LocalDateTime转LocalDate和LocalTime
        @Test
        public void LocalDateTest(){
            LocalDateTime localDateTime = LocalDateTime.now();
            LocalDate localDate = localDateTime.toLocalDate();
            LocalTime localTime = localDateTime.toLocalTime();
            System.out.println("当前日期为:" + localDate); 
            System.out.println("当前时间为:" + localTime);
        }
    
    image.png
    2、LocalDate转LocalDateTime

    我们在只有日期对象的前提下,是需要指定好确切的时间才可以转化为LocalDateTime对象,毕竟程序不可能凭空给我们生成一个时间对象。下面介绍几个常用的API

    名称 作用
    atStartOfDay 获取当天最早的LocalDateTime对象
    atTime(int hour, int minute) 获取指定时间的LocalDateTime对象
    atTime(int hour, int minute, int second) 获取指定时间的LocalDateTime对象
    atTime(OffsetTime time) 获取指定时间的LocalDateTime对象
    atTime(LocalTime time) 获取指定时间的LocalDateTime对象

    我们可以看到,LocalDate中提供了相当丰富的转化方法来给我们去进行时间对象的转换

        @Test
        public void LocalDateTest(){
           LocalDate localDate = LocalDate.now();
            LocalDateTime localDateTime1 = localDate.atStartOfDay();
            LocalDateTime localDateTime2 = localDate.atTime(8,30);
            LocalDateTime localDateTime3 = localDate.atTime(OffsetTime.MAX).toLocalDateTime();
            LocalDateTime localDateTime4 = localDate.atTime(LocalTime.now());
            System.out.println("localDateTime1时间为:" + localDateTime1);
            System.out.println("localDateTime2时间为:" + localDateTime2);
            System.out.println("localDateTime3时间为:" + localDateTime3);
            System.out.println("localDateTime4时间为:" + localDateTime4);
        }
    
    代码执行结果

    LocalDate可以转LocalDateTime对象的话,那么后续再转成LocalTime对象也就十分简单了,所以LocalDate转LocalTime这部分就不额外展开了。

    (七)其他API
    名称 作用
    range 获取给出指定字段的有效值范围
    isLeapYear 检查当年是否为闰年
    adjustInto 将指定的时间对象调整为与此对象具有相同的日期
    isSupported 检查是否支持给定的单位。在使用加减之前,我们可以检查是否支持给定的单位,否则我们可能会出错。
    until 计算两个日期之间的时间量
        @Test
        public void LocalDateTest(){
           LocalDate localDate = LocalDate.now();
           // range 的使用
            System.out.println("月份的范围为:" + localDate.range(ChronoField.MONTH_OF_YEAR));
            // isLeapYear 是否为闰年
            System.out.println("是否为闰年:" + localDate.isLeapYear());
            // adjustInto 把对象的日期复制给传入的时间对象
            Temporal resultDate = localDate.adjustInto(LocalDate.parse("2018-01-01"));
            System.out.println("复制后的结果如下:" + resultDate);
            // until
            System.out.println("间隔的月份数为:" + localDate.until(LocalDate.parse("2022-06-01")).getMonths());
            // isSupported
            System.out.println("对象是否支持年份计算" + localDate.isSupported(ChronoField.YEAR));
            System.out.println("对象是否支持小时计算" + localDate.isSupported(ChronoField.HOUR_OF_DAY));
        }
    
    代码执行结果

    三、java.util.Date类和LocalDate的区别

    1、java.util.Date类能表示的最早日期为1970-01-01,而LocalDate能表示的年份为-999999999 - 999999999,可以说从时间范围上来看,后者是远比前者要大的。
    2、LocalDate的API要更加的丰富和完善,且日期格式化也不需要专门创建一个日期格式化对象来处理
    3、LocalDate对象是线程安全的,而java.util.Date类则是线程不安全的。具体可以看下面这篇文章:

    LocalDateTime和Date的比较与区别

    实际上,LocalDate作为后来者在不少地方都实现了比Date类更加完善的功能

    PS:当遇到需要java.util.DateLocalDate类型的场景时,我们可以怎么实现呢?个人觉得可以定义一个统一的日期格式,借助字符串作为桥梁来转换。

        @Test
        public void UtilsDateTest(){
            Date date = new Date(0,10,10);
            String strDate = new SimpleDateFormat("yyyy - MM - dd").format(date);
            System.out.println("转换后的字符串日期为:" + strDate);
            LocalDate localDate = LocalDate.parse(strDate, DateTimeFormatter.ofPattern("yyyy - MM - dd"));
            System.out.println("转换后的LocalDate对象为:" + localDate);
        }
    

    总结

    至此,本篇文章对于LocalDate的介绍就到此介绍。LocalDate系列的日期时间类工具都有着十分实用的功能,适当了解相信可以在一定程度上为大家简化一下代码的开发。

    参考文章:

    【Java 8 新特性】Java LocalDate 详解
    https://blog.csdn.net/qq_42295268/article/details/112503983

    JDK官方文档:
    https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html
    https://www.concretepage.com/java/java-8/java-localdate

    相关文章

      网友评论

          本文标题:JDK新特性(六)LocalDate日期函数的使用

          本文链接:https://www.haomeiwen.com/subject/wvmasrtx.html