• Java日期时间API系列24-----Jdk8中java.time包中的新的日期时间API类,MonthDay类源码和应用,对比相同月日时间。


      Java8中为月日新增了类MonthDay,可以用来处理生日,节日、纪念日和星座等周期性问题。

    1.MonthDay

      特别需要注意的:它的默认打印格式会带前缀"--" ,比如--12-03,同样的默认解析格式也需要加前缀。

    1.1 部分源码

     * @implSpec
     * This class is immutable and thread-safe.
     *
     * @since 1.8
     */
    public final class MonthDay
            implements TemporalAccessor, TemporalAdjuster, Comparable<MonthDay>, Serializable {
    
        /**
         * Serialization version.
         */
        private static final long serialVersionUID = -939150713474957432L;
        /**
         * Parser.
         */
        private static final DateTimeFormatter PARSER = new DateTimeFormatterBuilder()
            .appendLiteral("--")
            .appendValue(MONTH_OF_YEAR, 2)
            .appendLiteral('-')
            .appendValue(DAY_OF_MONTH, 2)
            .toFormatter();
    
        /**
         * The month-of-year, not null.
         */
        private final int month;
        /**
         * The day-of-month.
         */
        private final int day;

    通过源码可以看出使用final修饰MonthDay,MonthDay是线程安全类,同时实现了TemporalAccessor, TemporalAdjuster, Comparable<MonthDay>, Serializable接口,有属性读取和设置等功能,但由于没有年部分,闰年2月29日的原因,没有加减功能。

     1.2 创建方式

         MonthDay monthDay1 = MonthDay.now();
            System.out.println(monthDay1);
            
            MonthDay monthDay2 = MonthDay.of(12, 3);
            System.out.println(monthDay2);

    输出:

    --02-29
    --12-03

    1.3 解析

    System.out.println(MonthDay.parse("--12-03"));

    2. 应用

    对比相同月日和推算等

    2.1 应用代码

        /**
         * 相同月日比较判断,用于生日,节日等周期性的日期比较判断。
         * @param localDate1
         * @param monthDay
         * @return
         */
        public static boolean isSameMonthDay(LocalDate localDate1, MonthDay monthDay){
            Objects.requireNonNull(localDate1, "localDate1");
            Objects.requireNonNull(monthDay, "monthDay");
            return MonthDay.of(localDate1.getMonthValue(), localDate1.getDayOfMonth()).equals(monthDay);
        }
        
        /**
         * 相同月日比较判断,用于生日,节日等周期性的日期比较判断。
         * @param localDate1
         * @param monthDayStr MM-dd格式
         * @return
         */
        public static boolean isSameMonthDay(LocalDate localDate1, String monthDayStr){
            Objects.requireNonNull(monthDayStr, "monthDayStr");
            return isSameMonthDay(localDate1, MonthDay.parse(MONTHDAY_FORMAT_PRE + monthDayStr));
        }
        
        /**
         * 相同月日比较判断,用于生日,节日等周期性的日期比较判断。
         * @param localDate1
         * @param localDate2
         * @return
         */
        public static boolean isSameMonthDay(LocalDate localDate1, LocalDate localDate2){
            Objects.requireNonNull(localDate2, "localDate2");
            return isSameMonthDay(localDate1, MonthDay.of(localDate2.getMonthValue(), localDate2.getDayOfMonth()));
        }
        
        /**
         * 相同月日比较判断,用于生日,节日等周期性的日期比较判断。
         * @param date
         * @param monthDayStr MM-dd格式
         * @return
         */
        public static boolean isSameMonthDay(Date date, String monthDayStr){
            return isSameMonthDay(DateTimeConverterUtil.toLocalDate(date), monthDayStr);
        }
        
        /**
         * 相同月日比较判断,用于生日,节日等周期性的日期比较判断。
         * @param date1
         * @param date2
         * @return
         */
        public static boolean isSameMonthDay(Date date1, Date date2){
            Objects.requireNonNull(date1, "date1");
            Objects.requireNonNull(date2, "date2");
            return isSameMonthDay(DateTimeConverterUtil.toLocalDate(date1), DateTimeConverterUtil.toLocalDate(date2));
        }
        
        /**
         * 相同月日比较判断,与当前日期对比,用于生日,节日等周期性的日期比较判断
         * @param monthDayStr MM-dd格式
         * @return
         */
        public static boolean isSameMonthDayOfNow(String monthDayStr){
            return isSameMonthDay(LocalDate.now(), monthDayStr);
        }
        
        /**
         * 下个固定月日相差天数,用于生日,节日等周期性的日期推算
         * @param localDate1
         * @param month
         * @param dayOfMonth
         * @return
         */
        public static long betweenNextSameMonthDay(LocalDate localDate1, int month, int dayOfMonth) {
            Objects.requireNonNull(localDate1, "localDate1");
            MonthDay monthDay1 = MonthDay.of(localDate1.getMonthValue(), localDate1.getDayOfMonth());
            MonthDay monthDay2 = MonthDay.of(month, dayOfMonth);
            
            // localDate1 月日 小于 month dayOfMonth
            if (monthDay1.compareTo(monthDay2) == -1) {
                return betweenTotalDays(localDate1.atStartOfDay(),
                        localDate1.withMonth(month).withDayOfMonth(dayOfMonth).atStartOfDay());
            } else {
                // 闰年2月29
                MonthDay leapMonthDay = MonthDay.of(2, 29);
                if (leapMonthDay.equals(monthDay2)) {
                    LocalDate nextLeapYear = nextLeapYear(localDate1);
                    return betweenTotalDays(localDate1.atStartOfDay(),
                            nextLeapYear.withMonth(month).withDayOfMonth(dayOfMonth).atStartOfDay());
                } else {
                    LocalDate next = localDate1.plusYears(1);
                    return betweenTotalDays(localDate1.atStartOfDay(),
                            next.withMonth(month).withDayOfMonth(dayOfMonth).atStartOfDay());
                }
            }
        }
        
        /**
         * 下个固定月日相差天数,用于生日,节日等周期性的日期推算
         * @param localDate
         * @param monthDayStr MM-dd格式
         * @return
         */
        public static long betweenNextSameMonthDay(LocalDate localDate, String monthDayStr) {
            Objects.requireNonNull(monthDayStr, "monthDayStr");
            MonthDay monthDay2 = MonthDay.parse(MONTHDAY_FORMAT_PRE + monthDayStr);
            return betweenNextSameMonthDay(localDate, monthDay2.getMonthValue(), monthDay2.getDayOfMonth());
        }
        
        /**
         * 下个固定月日相差天数,用于生日,节日等周期性的日期推算
         * @param date
         * @param monthDayStr MM-dd格式
         * @return
         */
        public static long betweenNextSameMonthDay(Date date, String monthDayStr) {
            Objects.requireNonNull(monthDayStr, "monthDayStr");
            MonthDay monthDay2 = MonthDay.parse(MONTHDAY_FORMAT_PRE + monthDayStr);
            return betweenNextSameMonthDay(DateTimeConverterUtil.toLocalDate(date), monthDay2.getMonthValue(),
                    monthDay2.getDayOfMonth());
        }
        
        /**
         * 下个固定月日相差天数,与当前日期对比,用于生日,节日等周期性的日期推算
         * @param monthDayStr MM-dd格式
         * @return
         */
        public static long betweenNextSameMonthDayOfNow(String monthDayStr) {
            Objects.requireNonNull(monthDayStr, "monthDayStr");
            MonthDay monthDay2 = MonthDay.parse(MONTHDAY_FORMAT_PRE + monthDayStr);
            return betweenNextSameMonthDay(LocalDate.now(), monthDay2.getMonthValue(),
                    monthDay2.getDayOfMonth());
        }
        
        /**
         * 下个固定月日相差日期,用于生日,节日等周期性的日期推算
         * @param localDate
         * @param monthDayStr MM-dd格式
         * @return
         */
        public static LocalDate nextSameMonthDay(LocalDate localDate, String monthDayStr){
            return localDate.plusDays(betweenNextSameMonthDay(localDate, monthDayStr));
        }
        
        /**
         * 下个固定月日相差日期,用于生日,节日等周期性的日期推算
         * @param date
         * @param monthDayStr MM-dd格式
         * @return
         */
        public static Date nextSameMonthDay(Date date, String monthDayStr){
            return DateTimeConverterUtil.toDate(nextSameMonthDay(DateTimeConverterUtil.toLocalDate(date), monthDayStr));
        }
        
        /**
         * 下个固定月日相差日期,与当前日期对比,用于生日,节日等周期性的日期推算
         * @param monthDayStr MM-dd格式
         * @return
         */
        public static Date nextSameMonthDayOfNow(String monthDayStr){
            return nextSameMonthDay(new Date(), monthDayStr);
        }

    2.2 测试代码

        /**
         * 相同月日对比
         */
        @Test
        public void sameMonthDayTest(){
            Date date = DateTimeCalculatorUtil.getDate(2020, 2, 29);
            System.out.println(date);
            
            //date的月日部分是否和02-29相等
            System.out.println(DateTimeCalculatorUtil.isSameMonthDay(date, "02-29"));
            //date的月日部分是否和new Date()的月日部分相等
            System.out.println(DateTimeCalculatorUtil.isSameMonthDay(date, new Date()));
            //当前时间月日部分是否和02-29相等
            System.out.println(DateTimeCalculatorUtil.isSameMonthDayOfNow("02-29"));
            
            //date的月日部分和下一个03-05相差天数
            System.out.println(DateTimeCalculatorUtil.betweenNextSameMonthDay(date, "03-05"));
            //当前时间月日部分和下一个03-05相差天数
            System.out.println(DateTimeCalculatorUtil.betweenNextSameMonthDayOfNow("03-05"));
            
            //date为准,下一个02-14的日期
            System.out.println(DateTimeCalculatorUtil.nextSameMonthDay(date, "02-14"));
            //date为准,下一个03-05的日期
            System.out.println(DateTimeCalculatorUtil.nextSameMonthDay(date, "03-05"));
            //date为准,下一个02-29的日期 ,02-29 只有闰年有。
            System.out.println(DateTimeCalculatorUtil.nextSameMonthDay(date, "02-29"));
            //当前时间为准,下一个02-29的日期  ,02-29 只有闰年有。
            System.out.println(DateTimeCalculatorUtil.nextSameMonthDayOfNow("02-29"));
        }

    2.3 输出

    Sat Feb 29 00:00:00 CST 2020
    true
    true
    true
    5
    5
    Sun Feb 14 00:00:00 CST 2021
    Thu Mar 05 00:00:00 CST 2020
    Thu Feb 29 00:00:00 CST 2024
    Thu Feb 29 00:00:00 CST 2024

    源代码地址:https://github.com/xkzhangsan/xk-time

  • 相关阅读:
    块存储、文件存储、对象存储的区别
    brk 和 sbrk 区别
    【转】海量数据处理:十道面试题与十个海量数据处理方法总结
    C++ STL 里为什么不维护一个 size 成员变量?
    C++对象内存分布详解(包括字节对齐和虚函数表)
    虚函数实现原理
    关于Ubuntu中Could not get lock /var/lib/dpkg/lock解决方案
    Jerasure 1.2A 中的 C 函数 tips
    C++ qsort() 函数调用时实参与形参不兼容的问题解决
    C语言位运算符:与、或、异或、取反、左移与右移详细介绍
  • 原文地址:https://www.cnblogs.com/xkzhangsanx/p/12384227.html
Copyright © 2020-2023  润新知