• 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

     

     

  • 相关阅读:
    x64 平台开发 Mapxtreme 编译错误
    hdu 4305 Lightning
    Ural 1627 Join(生成树计数)
    poj 2104 Kth Number(可持久化线段树)
    ural 1651 Shortest Subchain
    hdu 4351 Digital root
    hdu 3221 Bruteforce Algorithm
    poj 2892 Tunnel Warfare (Splay Tree instead of Segment Tree)
    hdu 4031 Attack(BIT)
    LightOJ 1277 Looking for a Subsequence
  • 原文地址:https://www.cnblogs.com/xkzhangsanx/p/12546684.html
Copyright © 2020-2023  润新知