zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Leetcode 50.Pow(x,n) By Python
    Leetcode 347.前K个高频元素 By Python
    Leetcode 414.Fizz Buzz By Python
    Leetcode 237.删除链表中的节点 By Python
    Leetcode 20.有效的括号 By Python
    Leetcode 70.爬楼梯 By Python
    Leetcode 190.颠倒二进制位 By Python
    团体程序设计天梯赛 L1-034. 点赞
    Wannafly挑战赛9 C-列一列
    TZOJ Start
  • 原文地址:https://www.cnblogs.com/xkzhangsanx/p/12384227.html
Copyright © 2011-2022 走看看