• Java日期时间API系列28-----Jdk8中java.time包中的新的日期时间API类,计算节假日和二十四节气。


    1.节日信息计算代码

    package com.xkzhangsan.time.holiday;
    
    import java.time.DayOfWeek;
    import java.time.LocalDate;
    import java.time.MonthDay;
    import java.time.temporal.ChronoField;
    import java.time.temporal.ChronoUnit;
    import java.time.temporal.Temporal;
    import java.time.temporal.TemporalAdjusters;
    import java.util.Date;
    import java.util.Map;
    import java.util.Map.Entry;
    import java.util.Objects;
    
    import com.xkzhangsan.time.LunarDate;
    import com.xkzhangsan.time.constants.Constant;
    import com.xkzhangsan.time.converter.DateTimeConverterUtil;
    import com.xkzhangsan.time.formatter.DateTimeFormatterUtil;
    import com.xkzhangsan.time.utils.CollectionUtil;
    import com.xkzhangsan.time.utils.StringUtil;
    
    /**
     * 节日处理
     * 包含
     * 1.公历节假日计算, getLocalHoliday* 比如getLocalHoliday(Date date) 计算date的公历节日,getLocalHoliday(Date date, Map<String, String> localHolidayMap) 可以传入自定义公历节日数据
     * 2.农历节假日计算, getChineseHoliday* 比如getChineseHoliday(Date date) 计算date的农历节日,getChineseHoliday(Date date, Map<String, String> chineseHolidayMap) 可以传入自定义农历节日数据
     * 3.二十四节气计算, getSolarTerm* 比如getSolarTerm(Date date) 计算date的二十四节气
     * 
     * 农历相关,仅支持公历1901-2050年的计算
    * @ClassName: Holiday
    * @Description: Holiday
    * @author xkzhangsan
    * @date 2019年12月30日
    * @version 0.2 试用
     */
    public interface Holiday {
        
        /**
         * 根据日期获取公历节日
         * @param date
         * @return
         */
        static String getLocalHoliday(Date date){
            return getLocalHoliday(date, null);
        }
        
        /**
         * 根据日期获取公历节日
         * @param date
         * @param localHolidayMap 自定义节日数据,特殊节日如,"母亲节", "5-W-2-7" 5表示5月,W表示星期,2表示第二个星期,7表示星期的第7天
         * @return
         */
        static String getLocalHoliday(Date date, Map<String, String> localHolidayMap){
            Objects.requireNonNull(date, "date");
            return getLocalHoliday(DateTimeConverterUtil.toLocalDateTime(date), localHolidayMap);
        }
        
        /**
         * 根据日期获取公历节日
         * @param temporal 支持 LocalDate、LocalDateTime、Instant和ZonedDateTime
         * @return
         */
        static String getLocalHoliday(Temporal temporal){
            return getLocalHoliday(temporal, null);
        }
        
        /**
         * 根据日期获取公历节日
         * @param temporal 支持 LocalDate、LocalDateTime、Instant和ZonedDateTime
         * @param localHolidayMap 自定义节日数据,特殊节日如,"母亲节", "5-W-2-7" 5表示5月,W表示星期,2表示第二个星期,7表示星期的第7天
         * @return
         */
        static String getLocalHoliday(Temporal temporal, Map<String, String> localHolidayMap){
            Objects.requireNonNull(temporal, "temporal");
            String localHoliday = "";
            if(CollectionUtil.isEmpty(localHolidayMap)){
                localHolidayMap = LocalHolidayEnum.convertToMap();
            }
            
            MonthDay monthDay = MonthDay.from(temporal);
            String monthDayStr = monthDay.format(DateTimeFormatterUtil.MMDD_FMT);
            for(Entry<String, String> entry : localHolidayMap.entrySet()){
                if (entry.getKey().equals(monthDayStr)) {
                    if(StringUtil.isEmpty(localHoliday)){
                        localHoliday = entry.getValue();
                    }else{
                        localHoliday = localHoliday + " " +entry.getValue();
                    }
                }
                //如果为特殊格式,解析对比
                if (entry.getKey().contains("W")) {
                    String[] arr = entry.getKey().split("-");
                    int month = Integer.parseInt(arr[0]);
                    int weekIndex = Integer.parseInt(arr[2]);
                    int weekValue = Integer.parseInt(arr[3]);
                    DayOfWeek dow = DayOfWeek.of(weekValue);
                    //设置到当前节日的月份
                    Temporal tempTem = temporal.with(ChronoField.MONTH_OF_YEAR, month);
                    //设置到当前节日的第几星期第几天
                    Temporal targetTem = tempTem.with(TemporalAdjusters.dayOfWeekInMonth(weekIndex, dow));
                    MonthDay targetMonthDay = MonthDay.from(targetTem);
                    String targetMonthDayStr = targetMonthDay.format(DateTimeFormatterUtil.MMDD_FMT);
                    if (monthDayStr.equals(targetMonthDayStr)) {
                        if(StringUtil.isEmpty(localHoliday)){
                            localHoliday = entry.getValue();
                        }else{
                            localHoliday = localHoliday + " " +entry.getValue();
                        }
                    }
                }
            }
            return localHoliday;
        }
        
        /**
         * 根据日期获取农历几日
         * @param date
         * @return
         */
        static String getChineseHoliday(Date date){
            return getChineseHoliday(date, null);
        }
        
        /**
         * 根据日期获取农历几日
         * @param date
         * @param chineseHolidayMap 自定义节日数据,特殊节日如除夕 用CHUXI表示
         * @return
         */
        static String getChineseHoliday(Date date, Map<String, String> chineseHolidayMap){
            Objects.requireNonNull(date, "date");
            return getChineseHoliday(DateTimeConverterUtil.toLocalDateTime(date), chineseHolidayMap);
        }
        
        /**
         * 根据日期获取农历几日
         * @param temporal 支持 LocalDate、LocalDateTime、Instant和ZonedDateTime 支持 LocalDate、LocalDateTime、Instant和ZonedDateTime
         * @return
         */
        static String getChineseHoliday(Temporal temporal){
            return getChineseHoliday(temporal, null);
        }
        
        /**
         * 根据日期获取农历几日
         * @param temporal 支持 LocalDate、LocalDateTime、Instant和ZonedDateTime
         * @param chineseHolidayMap 自定义节日数据,特殊节日如除夕 用CHUXI表示
         * @return
         */
        static String getChineseHoliday(Temporal temporal, Map<String, String> chineseHolidayMap){
            Objects.requireNonNull(temporal, "temporal");
            String chineseHoliday = "";
            if(CollectionUtil.isEmpty(chineseHolidayMap)){
                chineseHolidayMap = ChineseHolidayEnum.convertToMap();
            }
            
            LunarDate lunarDate = LunarDate.from(temporal);
            
            //闰月不计算节假日
            if(StringUtil.isNotEmpty(lunarDate.getLeapMonthCn())){
                return chineseHoliday;
            }
            String monthDayStr = lunarDate.formatShort();
            //对比枚举日期,返回假日
            for(Entry<String, String> entry : chineseHolidayMap.entrySet()){
                if (entry.getKey().equals(monthDayStr)) {
                    if(StringUtil.isEmpty(chineseHoliday)){
                        chineseHoliday = entry.getValue();
                    }else{
                        chineseHoliday = chineseHoliday + " " +entry.getValue();
                    }
                }
                //如果为特殊节日除夕
                if (entry.getKey().equals(Constant.CHUXI)) {
                    LocalDate tempLocalDate = lunarDate.getLocalDate();
                    LocalDate targetLocalDate = tempLocalDate.plus(1, ChronoUnit.DAYS);
                    LunarDate targetLunarDate = LunarDate.from(targetLocalDate);
                    String targetMonthDayStr = targetLunarDate.formatShort();
                    if(Constant.CHUNJIE.equals(targetMonthDayStr)){
                        if(StringUtil.isEmpty(chineseHoliday)){
                            chineseHoliday = entry.getValue();
                        }else{
                            chineseHoliday = chineseHoliday + " " +entry.getValue();
                        }
                    }
                }
            }
            return chineseHoliday;
        }
        
        /**
         * 根据日期获取二十四节气
         * @param date
         * @return
         */
        static String getSolarTerm(Date date){
            Objects.requireNonNull(date, "date");
            LunarDate lunarDate = LunarDate.from(date);
            return lunarDate.getSolarTerm();
        }
        
        /**
         * 根据日期获取二十四节气
         * @param temporal 支持 LocalDate、LocalDateTime、Instant和ZonedDateTime
         * @return
         */
        static String getSolarTerm(Temporal temporal){
            Objects.requireNonNull(temporal, "temporal");
            LunarDate lunarDate = LunarDate.from(temporal);
            return lunarDate.getSolarTerm();
        }
    }

    (1)getLocalHoliday(Date date, Map<String, String> localHolidayMap)中"母亲节", "5-W-2-7" 5表示5月,W表示星期,2表示第二个星期,7表示星期的第7天。

    使用临时变量,修改月份为5月,然后使用TemporalAdjusters.dayOfWeekInMonth来计算当前月第几周第几天的日期和传入日期对比。

    (2)getChineseHoliday(Date date, Map<String, String> chineseHolidayMap) 特殊节日如除夕 用CHUXI

    除夕是一年的最后一天和闰年2月类似,具体日期不确定,使用临时变量,当前日期加一天后为春节,则传入日期为除夕。

    (3)getSolarTerm(Date date)

    这里使用LunarDate lunarDate = LunarDate.from(date),将当前日期转换为农历日期,获取它的节气信息。

    具体可以看Java日期时间API系列11-----Jdk8中java.time包中的新的日期时间API类,使用java8日期时间API重写农历LunarDate 的calElement(int, int, int)方法。

    2.测试代码

        /**
         * 公历节日,母亲节
         */
        @Test
        public void localHolidayEnumTest(){
            LocalDate localDate = LocalDate.of(2020, 5, 10);
            System.out.println(Holiday.getLocalHoliday(localDate));
            
            //自定义节日数据
            Map<String, String> localHolidayMap = new HashMap<String, String>();
            localHolidayMap.put("0422", "世界地球日");
            LocalDate localDate2 = LocalDate.of(2020, 4, 22);
            System.out.println(Holiday.getLocalHoliday(localDate2, localHolidayMap));
        }
        
        /**
         * 农历节日,除夕
         */
        @Test
        public void chineseHolidayEnumTest(){
            LocalDate localDate = LocalDate.of(2020, 1, 24);
            System.out.println("localDate:"+Holiday.getChineseHoliday(localDate));
            
            //正常农历九月初九
            LocalDate localDate2 = LocalDate.of(2014, 10, 2);
            System.out.println("localDate2:"+Holiday.getChineseHoliday(localDate2));
            
            //正常农历闰九月初九  闰月不算节假日
            LocalDate localDate3 = LocalDate.of(2014, 11, 1);
            System.out.println("localDate3:"+Holiday.getChineseHoliday(localDate3));
        }
        
        /**
         * 二十四节气,2020-08-07 立秋
         */
        @Test
        public void solarTermEnumTest(){
            LocalDate localDate = LocalDate.of(2020, 8, 7);
            System.out.println(Holiday.getSolarTerm(localDate));
        }

    输出:

    母亲节
    世界地球日
    
    localDate:除夕
    localDate2:重阳节
    localDate3:
    
    立秋

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

     

     

  • 相关阅读:
    创业之死:97%的创业失败是因为…… . 分类: 项目管理 2014-06-18 17:56 315人阅读 评论(1) 收藏
    linux下的APK反编译软件及过程介绍 . 分类: arm-linux-Ubuntu 2014-06-18 17:51 400人阅读 评论(0) 收藏
    g++基本用法 分类: arm-linux-Ubuntu 2014-06-18 17:50 414人阅读 评论(0) 收藏
    更改 vc6 各窗口字体 (zz)
    程序员编程技术迅速提高终极攻略 (zz)
    A browser for WinCE/Windows base WebKit. (zz)
    输入一个十进制的数到dx_ax,然后十六进制转十进制输出
    汇编判断语句
    用结构体指针存储数据__正序_逆序下的输入
    二叉排序树
  • 原文地址:https://www.cnblogs.com/xkzhangsanx/p/12546684.html
Copyright © 2020-2023  润新知