• java 日历计算农历和节假日的工具类


    来源:

    https://www.cnblogs.com/LQBlog/p/10932246.html

     https://www.open-open.com/code/view/1430808632757

     java 日历计算农历和节假日的工具类

    背景

    业务需求需要后端提供这样的接口,网上找了很多java代码例子,虽然功能实现了 但是不完善,特别是节日那一块儿。然后百度发现有这样的插件,但是信息也是java后端提供的非js

    然后在开源js插件找到了下面这个js插件 根据修改源码转为java代码实现 java api暴露接口

    js插件

    源码

    复制代码
    package com.bozhi.core.util;
    
    
    import java.math.BigDecimal;
    import java.text.DateFormat;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.*;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    /**
     * @Auther: liqiang
     * @Date: 2019/5/27 11:54
     * @Description: 计算农历节假日信息
     *         SimpleCalendar.Element element=SimpleCalendar.getCalendarDetail("2019-06-06","yyyy-MM-dd");
     *         element=SimpleCalendar.getCalendarDetail("2019-06-04","yyyy-MM-dd");
     */
    public class SimpleCalendar {
        long[] lunarInfo = new long[]{
                0x4bd8, 0x4ae0, 0xa570, 0x54d5, 0xd260, 0xd950, 0x5554, 0x56af, 0x9ad0, 0x55d2,
                0x4ae0, 0xa5b6, 0xa4d0, 0xd250, 0xd255, 0xb54f, 0xd6a0, 0xada2, 0x95b0, 0x4977,
                0x497f, 0xa4b0, 0xb4b5, 0x6a50, 0x6d40, 0xab54, 0x2b6f, 0x9570, 0x52f2, 0x4970,
                0x6566, 0xd4a0, 0xea50, 0x6a95, 0x5adf, 0x2b60, 0x86e3, 0x92ef, 0xc8d7, 0xc95f,
                0xd4a0, 0xd8a6, 0xb55f, 0x56a0, 0xa5b4, 0x25df, 0x92d0, 0xd2b2, 0xa950, 0xb557,
                0x6ca0, 0xb550, 0x5355, 0x4daf, 0xa5b0, 0x4573, 0x52bf, 0xa9a8, 0xe950, 0x6aa0,
                0xaea6, 0xab50, 0x4b60, 0xaae4, 0xa570, 0x5260, 0xf263, 0xd950, 0x5b57, 0x56a0,
                0x96d0, 0x4dd5, 0x4ad0, 0xa4d0, 0xd4d4, 0xd250, 0xd558, 0xb540, 0xb6a0, 0x95a6,
                0x95bf, 0x49b0, 0xa974, 0xa4b0, 0xb27a, 0x6a50, 0x6d40, 0xaf46, 0xab60, 0x9570,
                0x4af5, 0x4970, 0x64b0, 0x74a3, 0xea50, 0x6b58, 0x5ac0, 0xab60, 0x96d5, 0x92e0,
                0xc960, 0xd954, 0xd4a0, 0xda50, 0x7552, 0x56a0, 0xabb7, 0x25d0, 0x92d0, 0xcab5,
                0xa950, 0xb4a0, 0xbaa4, 0xad50, 0x55d9, 0x4ba0, 0xa5b0, 0x5176, 0x52bf, 0xa930,
                0x7954, 0x6aa0, 0xad50, 0x5b52, 0x4b60, 0xa6e6, 0xa4e0, 0xd260, 0xea65, 0xd530,
                0x5aa0, 0x76a3, 0x96d0, 0x4afb, 0x4ad0, 0xa4d0, 0xd0b6, 0xd25f, 0xd520, 0xdd45,
                0xb5a0, 0x56d0, 0x55b2, 0x49b0, 0xa577, 0xa4b0, 0xaa50, 0xb255, 0x6d2f, 0xada0,
                0x4b63, 0x937f, 0x49f8, 0x4970, 0x64b0, 0x68a6, 0xea5f, 0x6b20, 0xa6c4, 0xaaef,
                0x92e0, 0xd2e3, 0xc960, 0xd557, 0xd4a0, 0xda50, 0x5d55, 0x56a0, 0xa6d0, 0x55d4,
                0x52d0, 0xa9b8, 0xa950, 0xb4a0, 0xb6a6, 0xad50, 0x55a0, 0xaba4, 0xa5b0, 0x52b0,
                0xb273, 0x6930, 0x7337, 0x6aa0, 0xad50, 0x4b55, 0x4b6f, 0xa570, 0x54e4, 0xd260,
                0xe968, 0xd520, 0xdaa0, 0x6aa6, 0x56df, 0x4ae0, 0xa9d4, 0xa4d0, 0xd150, 0xf252,
                0xd520};
        List<Element> elements=new ArrayList<Element>();
        public static  Map<String,SimpleCalendar> cache=new HashMap<String,SimpleCalendar>();
        long[] solarMonth = new long[]{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        String[] Gan = new String[]{"甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"};
        String[] Zhi = new String[]{"子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"};
        String[] Animals = new String[]{"鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪"};
        String[] solarTerm = new String[]{"小寒", "大寒", "立春", "雨水", "惊蛰", "春分", "清明", "谷雨", "立夏", "小满", "芒种", "夏至", "小暑", "大暑", "立秋", "处暑", "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪", "冬至"};
        int[] sTermInfo = new int[]{0, 21208, 42467, 63836, 85337, 107014, 128867, 150921, 173149, 195551, 218072, 240693, 263343, 285989, 308563, 331033, 353350, 375494, 397447, 419210, 440795, 462224, 483532, 504758};
        char[] nStr1 = new char[]{'日', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十'};
        String[] nStr2 = new String[]{"初", "十", "廿", "卅", " "};
    
       static String[] monthChinese=new String[]{ "一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二" };
        static  String []dayChinese=new String[]{"一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二","十三","十四","十五","十六","十七","十八","十九","二十","二十一","二十二","二十三","二十四","二十五","二十六","二十七","二十八","二十九","三十","三十一"};
        char[] jcName0 = new char[]{'建', '除', '满', '平', '定', '执', '破', '危', '成', '收', '开', '闭'};
        char[] jcName1 = new char[]{'闭', '建', '除', '满', '平', '定', '执', '破', '危', '成', '收', '开'};
        char[] jcName2 = new char[]{'开', '闭', '建', '除', '满', '平', '定', '执', '破', '危', '成', '收'};
        char[] jcName3 = new char[]{'收', '开', '闭', '建', '除', '满', '平', '定', '执', '破', '危', '成'};
        char[] jcName4 = new char[]{'成', '收', '开', '闭', '建', '除', '满', '平', '定', '执', '破', '危'};
        char[] jcName5 = new char[]{'危', '成', '收', '开', '闭', '建', '除', '满', '平', '定', '执', '破'};
        char[] jcName6 = new char[]{'破', '危', '成', '收', '开', '闭', '建', '除', '满', '平', '定', '执'};
        char[] jcName7 = new char[]{'执', '破', '危', '成', '收', '开', '闭', '建', '除', '满', '平', '定'};
        char[] jcName8 = new char[]{'定', '执', '破', '危', '成', '收', '开', '闭', '建', '除', '满', '平'};
        char[] jcName9 = new char[]{'平', '定', '执', '破', '危', '成', '收', '开', '闭', '建', '除', '满'};
        char[] jcName10 = new char[]{'满', '平', '定', '执', '破', '危', '成', '收', '开', '闭', '建', '除'};
        char[] jcName11 = new char[]{'除', '满', '平', '定', '执', '破', '危', '成', '收', '开', '闭', '建'};
    
        //国历节日  *表示放假日
        String[] sFtv = new String[]{
                "0101*元旦",
                "0106  中国13亿人口日",
                "0110  中国110宣传日",
    
                "0202  世界湿地日",
                "0204  世界抗癌症日",
                "0210  世界气象日",
                "0214  情人节",
                "0221  国际母语日",
                "0207  国际声援南非日",
    
                "0303  全国爱耳日",
                "0308  妇女节",
                "0312  植树节 孙中山逝世纪念日",
                "0315  消费者权益保护日",
                "0321  世界森林日",
                "0322  世界水日",
                "0323  世界气象日",
                "0324  世界防治结核病日",
    
                "0401  愚人节",
                "0407  世界卫生日",
                "0422  世界地球日",
    
                "0501*国际劳动节",
                "0504  中国青年节",
                "0505  全国碘缺乏病日",
                "0508  世界红十字日",
                "0512  国际护士节",
                "0515  国际家庭日",
                "0517  世界电信日",
                "0518  国际博物馆日",
                "0519  中国汶川地震哀悼日 全国助残日",
                "0520  全国学生营养日",
                "0522  国际生物多样性日",
                "0523  国际牛奶日",
                "0531  世界无烟日",
    
                "0601  国际儿童节",
                "0605  世界环境日",
                "0606  全国爱眼日",
                "0617  防治荒漠化和干旱日",
                "0623  国际奥林匹克日",
                "0625  全国土地日",
                "0626  国际反毒品日",
    
                "0701  建党节 香港回归纪念日",
                "0707  抗日战争纪念日",
                "0711  世界人口日",
    
                "0801  八一建军节",
                "0815  日本正式宣布无条件投降日",
    
                "0908  国际扫盲日",
                "0909  **逝世纪念日",
                "0910  教师节",
                "0916  国际臭氧层保护日",
                "0917  国际和平日",
                "0918  九·一八事变纪念日",
                "0920  国际爱牙日",
                "0927  世界旅游日",
                "0928  孔子诞辰",
    
                "1001*国庆节 国际音乐节 国际老人节",
                "1002  国际减轻自然灾害日",
                "1004  世界动物日",
                "1007  国际住房日",
                "1008  世界视觉日 全国高血压日",
                "1009  世界邮政日",
                "1010  辛亥革命纪念日 世界精神卫生日",
                "1015  国际盲人节",
                "1016  世界粮食节",
                "1017  世界消除贫困日",
                "1022  世界传统医药日",
                "1024  联合国日",
                "1025  人类天花绝迹日",
                "1026  足球诞生日",
                "1031  万圣节",
    
                "1107  十月社会主义革命纪念日",
                "1108  中国记者日",
                "1109  消防宣传日",
                "1110  世界青年节",
                "1112  孙中山诞辰",
                "1114  世界糖尿病日",
                "1117  国际大学生节",
    
                "1201  世界艾滋病日",
                "1203  世界残疾人日",
                "1209  世界足球日",
                "1210  世界人权日",
                "1212  西安事变纪念日",
                "1213  南京大屠杀",
                "1220  澳门回归纪念日",
                "1221  国际篮球日",
                "1224  平安夜",
                "1225  圣诞节 世界强化免疫日",
                "1226  **诞辰"};
        //农历节日  *表示放假日
        String[] lFtv = new String[]{
                "0101*春节",
                "0102*大年初二",
                "0103*大年初三",
                "0104*大年初四",
                "0105*大年初五",
                "0106*大年初六",
                "0107*大年初七",
                "0105  路神生日",
                "0115  元宵节",
                "0202  龙抬头",
                "0219  观世音圣诞",
                "0404  寒食节",
                "0408  佛诞节 ",
                "0505*端午节",
                "0606  天贶节 姑姑节",
                "0624  彝族火把节",
                "0707  七夕情人节",
                "0714  鬼节(南方)",
                "0715  盂兰节",
                "0730  地藏节",
                "0815*中秋节",
                "0909  重阳节",
                "1001  祭祖节",
                "1117  阿弥陀佛圣诞",
                "1208  腊八节 释迦如来成道日",
                "1223  过小年",
                "1229*腊月二十九",
                "0100*除夕"};
        //某月的第几个星期几; 5,6,7,8 表示到数第 1,2,3,4 个星期几
        String[] wFtv = new String[]{
                "0110  黑人节",
                "0150  世界麻风日",
                "0121  日本成人节",
                "0520  母亲节",
                "0530  全国助残日",
                "0630  父亲节",
                "0716  合作节",
                "0730  被奴役国家周",
                "0932  国际和平日",
                "0940  国际聋人节 世界儿童日",
                "1011  国际住房日",
                "1144  感恩节"};
        private Long length;//公历当月天数
        private int firstWeek;  //公历当月1日星期几
        public static Element getCalendarDetail(Date date) throws ParseException {
    
    
            Calendar cal = Calendar.getInstance() ;
            cal.setTime(date);
            int year=cal.get(Calendar.YEAR);
            int month=cal.get(Calendar.MONTH);
            String cacheKey=(year+"-"+month);
            SimpleCalendar lunarCalendarUtil=null;
            if(false){
                lunarCalendarUtil=cache.get(cacheKey);
            }else {
                lunarCalendarUtil=new SimpleCalendar();
                lunarCalendarUtil.calendar(year, month);
                cache.put(cacheKey,lunarCalendarUtil);
            }
    
            return lunarCalendarUtil.getElements().get(cal.get(Calendar.DATE)-1);
        }
    
        public static Element getCalendarDetail(String date,String pattern) throws ParseException {
            SimpleDateFormat df2 = new SimpleDateFormat(pattern);
            return getCalendarDetail(df2.parse(date));
        }
    
        public List<Element> getElements() {
            return elements;
        }
    
        public void setElements(List<Element> elements) {
            this.elements = elements;
        }
    
        public void calendar(int y, int m) throws ParseException {
            Date sDObj = null;
            Lunar lDObj = null;
            Boolean lL=null;
            Long lD2=null;
            Integer lY = null, lM=null, lD = 1, lX = 0, tmp1, tmp2, lM2, lY2=null, tmp3, dayglus, bsg, xs, xs1, fs, fs1, cs, cs1=null;
            String cY, cM, cD; //年柱,月柱,日柱
            Integer[] lDPOS = new Integer[3];
            Integer n = 0;
            Integer firstLM = 0;
            String dateString = y + "-" +(m+1) + "-" + 1;
            sDObj = new SimpleDateFormat("yyyy-MM-dd").parse(dateString);
    
            this.length = solarDays(y, m);    //公历当月天数
            this.firstWeek = sDObj.getDay();    //公历当月1日星期几
    
            ////////年柱 1900年立春后为庚子年(60进制36)
            if (m < 2) cY = cyclical(y - 1900 + 36 - 1);
            else cY = cyclical(y - 1900 + 36);
            int term2 = sTerm(y, 2); //立春日期
    
            ////////月柱 1900年1月小寒以前为 丙子月(60进制12)
            int firstNode = sTerm(y, m * 2);//返回当月「节」为几日开始
            cM = cyclical((y - 1900) * 12 + m + 12);
    
            lM2 = (y - 1900) * 12 + m + 12;
            //当月一日与 1900/1/1 相差天数
            //1900/1/1与 1970/1/1 相差25567日, 1900/1/1 日柱为甲戌日(60进制10)
            SimpleDateFormat df2 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            df2.setTimeZone(TimeZone.getTimeZone("UTC"));
            Date date = df2.parse("" + y + "-" + (m+1) + "-" + 1 + " 00:00:00");
    
            long dayCyclical = date.getTime() / 86400000 + 25567 + 10;
            //// long dayCyclical =date.getTime() / 86400000 + 25567 + 10;
            SimpleDateFormat df3 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            for (int i = 0; i < this.length; i++) {
                if(i==18){
                    int b=5;
                }
                if (lD > lX) {
                    sDObj= df3.parse("" + y + "-" + (m+1) + "-" + (i+1) + " 00:00:00");   //当月一日日期
                    lDObj = new Lunar(sDObj);     //农历
                    lY = lDObj.year;           //农历年
                    lM = lDObj.month;          //农历月
                    lD = lDObj.day;            //农历日
                    lL = lDObj.isLeap;         //农历是否闰月
                    lX = lL ? leapDays(lY) : monthDays(lY, lM); //农历当月最后一天
    
                    if (n == 0) firstLM = lM;
    
                    lDPOS[n++] = i - lD + 1;
                }
    
                //依节气调整二月分的年柱, 以立春为界
                if (m == 1 && (i + 1) == term2) {
                    cY = cyclical(y - 1900 + 36);
                    lY2 = (y - 1900 + 36);
                }
                //依节气月柱, 以「节」为界
                if ((i + 1) == firstNode) {
                    cM = cyclical((y - 1900) * 12 + m + 13);
                    lM2 = (y - 1900) * 12 + m + 13;
                }
                //日柱
                cD = cyclical(dayCyclical + i);
                lD2 = (dayCyclical + i);
                Element element = new Element(y, m + 1, i + 1, (nStr1[(i + this.firstWeek) % 7]),
                        lY, lM, lD++, lL,
                        cY, cM, cD);
                element.setcDay(cDay(element.getlDay()));
                int paramterLy2=lY2==null?-1:(lY2 % 12);
                int paramterLm2=lM2==null?-1:lM2 % 12;
                long paramterLd2=lD2==null?-1:lD2 % 12;
                int paramterLy2b=lY2==null?-1:lY2 % 10;
                int paramterLy2c= (int) (lD2==null?-1:lD2 % 10);
                int paramterLld=lD==null?-1:lD - 1;
                element.setSgz5(CalConv2(paramterLy2, paramterLm2, (int) paramterLd2, paramterLy2b,paramterLy2c , lM,paramterLld , m + 1, cs1==null?-1:cs1));
                element.setSgz3(cyclical6(lM2 % 12, (int) ((lD2) % 12)));
                elements.add(element);
    
    
            }
    
            //节气
            tmp1 = sTerm(y, m * 2) - 1;
            tmp2 = sTerm(y, m * 2 + 1) - 1;
            elements.get(tmp1).solarTerms = solarTerm[m * 2];
            elements.get(tmp2).solarTerms = solarTerm[m * 2 + 1];
            if (m == 3) elements.get(tmp1).color = "red"; //清明颜色
    
            Pattern p = Pattern.compile("^(\\d{2})(\\d{2})([\\s\\*])(.+)$");
            //国历节日
            for (String i : sFtv){
                Matcher matcher=p.matcher(i);
                if (matcher.matches()) {
                    if(i.equals("1212  西安事变纪念日")){
                        int j=2;
                    }
                    if (Integer.valueOf(matcher.group(1)).intValue() == (m + 1)) {
                        elements.get(Integer.valueOf(matcher.group(2)) - 1).solarFestival +=matcher.group(4)+"";
                        if (matcher.group(3).equals('*'))   elements.get(Integer.valueOf(matcher.group(0)) - 1).color = "red";
                    }
                }
            }
    
            p = Pattern.compile("^(\\d{2})(.{2})([\\s\\*])(.+)$");
            //农历节日
            for (String i  :  lFtv){
                Matcher matcher=p.matcher(i);
                if (matcher.matches()) {
                    tmp1 = Integer.valueOf(matcher.group(1)) - firstLM;
                    if (tmp1 == -11) tmp1 = 1;
                    if (tmp1 >= 0 && tmp1 < n) {
                        tmp2 = lDPOS[tmp1] +Integer.valueOf(matcher.group(2)) - 1;
                        if (tmp2 >= 0 && tmp2 < this.length) {
                            elements.get(tmp2).lunarFestival += matcher.group(4);
                            if (matcher.group(3).equals("*")) elements.get(tmp2).color = "red";
                        }
                    }
                }
            }
    
            //复活节只出现在3或4月
            if (m == 2 || m == 3) {
                Easter estDay = new Easter(y);
                if (m == estDay.m)
                    elements.get(estDay.d - 1).solarFestival = elements.get(estDay.d - 1).solarFestival + " 复活节(Easter Sunday)";
            }
    
    
            //黑色星期五
            if ((this.firstWeek + 12) % 7 == 5)
                elements.get(12).solarFestival += "黑色星期五";
    
            //今日
            //if (y == tY && m == tM) this[tD - 1].isToday = true;
        }
        //==============================返回公历 y年某m+1月的天数
        public long solarDays(int y, int m) {
            if (m == 1)
                return(((y % 4 == 0) && (y % 100 != 0) || (y % 400 == 0)) ? 29 : 28);
            else
                return(solarMonth[m]);
        }
        //============================== 返回阴历 (y年,m+1月)
        public char cyclical6(int num, int num2) {
            if (num == 0) return(jcName0[num2]);
            if (num == 1) return(jcName1[num2]);
            if (num == 2) return(jcName2[num2]);
            if (num == 3) return(jcName3[num2]);
            if (num == 4) return(jcName4[num2]);
            if (num == 5) return(jcName5[num2]);
            if (num == 6) return(jcName6[num2]);
            if (num == 7) return(jcName7[num2]);
            if (num == 8) return(jcName8[num2]);
            if (num == 9) return(jcName9[num2]);
            if (num == 10) return(jcName10[num2]);
            if (num == 11) return(jcName11[num2]);
            return '0';
        }
        public String  CalConv2(int yy,int  mm,int dd,int y,int d,int m, int dt,int  nm,int nd) {
            int dy = d  + dd;
            if ((yy == 0 && dd == 6) || (yy == 6 && dd == 0) || (yy == 1 && dd == 7) || (yy == 7 && dd == 1) || (yy == 2 && dd == 8) || (yy == 8 && dd == 2) || (yy == 3 && dd == 9) || (yy == 9 && dd == 3) || (yy == 4 && dd == 10) || (yy == 10 && dd == 4) || (yy == 5 && dd == 11) || (yy == 11 && dd == 5)) {
                return "<FONT color=#0000A0>日值岁破 大事不宜</font>";
            }
            else if ((mm == 0 && dd == 6) || (mm == 6 && dd == 0) || (mm == 1 && dd == 7) || (mm == 7 && dd == 1) || (mm == 2 && dd == 8) || (mm == 8 && dd == 2) || (mm == 3 && dd == 9) || (mm == 9 && dd == 3) || (mm == 4 && dd == 10) || (mm == 10 && dd == 4) || (mm == 5 && dd == 11) || (mm == 11 && dd == 5)) {
                return "<FONT color=#0000A0>日值月破 大事不宜</font>";
            }
            else if ((y == 0 && dy == 911) || (y == 1 && dy == 55) || (y == 2 && dy == 111) || (y == 3 && dy == 75) || (y == 4 && dy == 311) || (y == 5 && dy == 9) || (y == 6 && dy == 511) || (y == 7 && dy == 15) || (y == 8 && dy == 711) || (y == 9 && dy == 35)) {
                return "<FONT color=#0000A0>日值上朔 大事不宜</font>";
            }
            else if ((m == 1 && dt == 13) || (m == 2 && dt == 11) || (m == 3 && dt == 9) || (m == 4 && dt == 7) || (m == 5 && dt == 5) || (m == 6 && dt == 3) || (m == 7 && dt == 1) || (m == 7 && dt == 29) || (m == 8 && dt == 27) || (m == 9 && dt == 25) || (m == 10 && dt == 23) || (m == 11 && dt == 21) || (m == 12 && dt == 19)) {
                return "<FONT color=#0000A0>日值杨公十三忌 大事不宜</font>";
            }
            else {
                return "0";
            }
        }
        //    public Date getUtcDate(String dateStr){
    //        SimpleDateFormat df2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    //        df2.setTimeZone(TimeZone.getTimeZone("UTC"));
    //        Date date = df2.parse("1900-01-06 02:05:00");
    //    }
        //============================== 传入 offsenew Datet 返回干支, 0=甲子
        public String cyclical(long num) {
            return(Gan[(int) (num % 10)] + Zhi[(int) (num % 12)]);
        }
        //======================  中文日期
        public String cDay(int d) {
            String  s;
    
            switch (d) {
                case  10:
                    s = "初十";  break;
                case  20:
                    s = "二十";  break;
                case  30:
                    s = "三十";  break;
                default  :
                    s = nStr2[Double.valueOf(Math.floor(d / 10)).intValue()];
                    s += nStr1[d % 10];
            }
            return(s);
        }
        //===== 某年的第n个节气为几日(从0小寒起算)
        public int sTerm(int  y,int  n) throws ParseException {
            SimpleDateFormat df2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            df2.setTimeZone(TimeZone.getTimeZone("UTC"));
            Date date = df2.parse("1900-01-06 02:05:00");
            Long utcTime2=date.getTime();
            BigDecimal time2=new BigDecimal(31556925974.7).multiply(new BigDecimal(y - 1900)).add(new BigDecimal( sTermInfo[n]).multiply(BigDecimal.valueOf(60000L)));
            BigDecimal time=time2.add(BigDecimal.valueOf(utcTime2));
            Date offDate = new Date(time.longValue());
            Calendar cal = Calendar.getInstance() ;
            cal.setTimeZone(TimeZone.getTimeZone("UTC"));
            cal.setTime(offDate);
            int utcDate=cal.get(Calendar.DATE);
            //日期从0算起
            return utcDate;
        }
        //====================================== 返回农历 y年闰哪个月 1-12 , 没闰返回 0
        public Long  leapMonth(int y) {
            long lm = lunarInfo[y - 1900] & 0xf;
            return(lm == 0xf ? 0 : lm);
        }
        //====================================== 返回农历 y年的总天数
        public Long lYearDays(int y) {
            long i, sum = 348;
            for (i = 0x8000; i > 0x8; i >>= 1) sum += (lunarInfo[y - 1900] & i)!=0 ? 1 : 0;
            return(sum + leapDays(y));
        }
    
        //====================================== 返回农历 y年闰月的天数
        public int leapDays(int y) {
            if (leapMonth(y)!=0) return( (lunarInfo[y - 1899] & 0xf) == 0xf ? 30 : 29);
            else return 0;
        }
        //====================================== 返回农历 y年m月的总天数
        private int monthDays(int y,int m) {
            return( (lunarInfo[y - 1900] & (0x10000 >> m))!=0 ? 30 : 29 );
        }
    
        public   class Lunar{
            private  int year;
            private boolean isLeap;
            private  int month;
            private  int day;
            public Lunar(Date objDate) throws ParseException {
                int i, leap = 0, temp = 0;
                SimpleDateFormat df2 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
                df2.setTimeZone(TimeZone.getTimeZone("UTC"));
                DateFormat dtFmt = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
                Date date = df2.parse(  dtFmt.format(objDate));
                SimpleDateFormat df3 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
                df3.setTimeZone(TimeZone.getTimeZone("UTC"));
                Date date3 = df3.parse("" + 1900 + "-" + 1 + "-" + 31 + " 00:00:00");
                long time1=date.getTime();
                long time2=date3.getTime();
                int offset = (int)(( time1-time2) / 86400000);
                for (i = 1900; i < 2100 && offset > 0; i++) {
                    temp = lYearDays(i).intValue();
                    offset -= temp;
                }
    
                if (offset < 0) {
                    offset += temp;
                    i--;
                }
    
                this.year = i;
                leap = leapMonth(i).intValue(); //闰哪个月
                this.isLeap = false;
    
                for (i = 1; i < 13 && offset > 0; i++) {
                    //闰月
                    if (leap > 0 && i == (leap + 1) && this.isLeap == false) {
                        --i;
                        this.isLeap = true;
                        temp = leapDays(this.year);
                    }
                    else {
                        temp = monthDays(this.year, i);
                    }
    
                    //解除闰月
                    if (this.isLeap == true && i == (leap + 1)) this.isLeap = false;
    
                    offset -= temp;
                }
    
                if (offset == 0 && leap > 0 && i == leap + 1)
                    if (this.isLeap) {
                        this.isLeap = false;
                    }
                    else {
                        this.isLeap = true;
                        --i;
                    }
    
                if (offset < 0) {
                    offset += temp;
                    --i;
                }
    
                this.month = i;
                this.day = offset + 1;
            }
    
    
    
    
        }
    
        public class Easter{
    
            public int m;
            public int d;
            public Easter(int y) throws ParseException {
                int term2 = sTerm(y, 5); //取得春分日期
                SimpleDateFormat df2 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
                df2.setTimeZone(TimeZone.getTimeZone("UTC"));
                Date dayTerm2 = df2.parse("" +y + "-" +3 + "-" + term2 + " 00:00:00");//取得春分的公历日期控件(春分一定出现在3月)
                Lunar lDayTerm2 = new Lunar(dayTerm2); //取得取得春分农历
                int lMlen=0;
                if (lDayTerm2.day < 15) //取得下个月圆的相差天数
                    lMlen = 15 - lDayTerm2.day;
                else
                    lMlen = (lDayTerm2.isLeap ? leapDays(y) : monthDays(y, lDayTerm2.month)) - lDayTerm2.day + 15;
    
                //一天等于 1000*60*60*24 = 86400000 毫秒
                Date l15 = new Date(dayTerm2.getTime() + 86400000 * lMlen); //求出第一次月圆为公历几日
                Date dayEaster = new Date(l15.getTime() + 86400000 * ( 7 - l15.getDay() )); //求出下个周日
    
                this.m = dayEaster.getMonth();
                this.d = dayEaster.getDate();
            }
        }
        public static  class Element{
            public  int sYear;
            public int  sMonth;
            public int sDay;
            public char  week;
            public int lYear;
            public int  lMonth;
            public String lMonthChinese;
            public String lDayChinese;
            public int  lDay;
            public boolean  isLeap;
            public String  cYear;
            public String cMonth;
            public String cDay;
            public String color;
            public boolean isToday=false;
            public String lunarFestival;
            public String solarFestival;
            public String solarTerms;
            public String sgz5;
            public char sgz3;
            public Element(int sYear,int  sMonth, int sDay,char  week,int lYear,int  lMonth,int  lDay,boolean  isLeap,String  cYear, String cMonth, String cDay) {
    
                this.isToday = false;
                //瓣句
                this.sYear = sYear;   //公元年4位数字
                this.sMonth = sMonth;  //公元月数字
                this.sDay = sDay;    //公元日数字
                this.week = week;    //星期, 1个中文
                //农历
                this.lYear = lYear;   //公元年4位数字
                this.lMonth = lMonth;  //农历月数字
                this.lDay = lDay;    //农历日数字
                this.isLeap = isLeap;  //是否为农历闰月?
                //中文
                this.lMonthChinese=monthChinese[lMonth-1];
                this.lDayChinese=dayChinese[lDay-1];
                //八字
                this.cYear = cYear;   //年柱, 2个中文
                this.cMonth = cMonth;  //月柱, 2个中文
                this.cDay = cDay;    //日柱, 2个中文
    
                this.color = "";
    
                this.lunarFestival = ""; //农历节日
                this.solarFestival = ""; //公历节日
                this.solarTerms = ""; //节气
            }
    
            public String getSgz5() {
                return sgz5;
            }
    
            public void setSgz5(String sgz5) {
                this.sgz5 = sgz5;
            }
    
            public char getSgz3() {
                return sgz3;
            }
    
            public void setSgz3(char sgz3) {
                this.sgz3 = sgz3;
            }
    
            public int getsYear() {
                return sYear;
            }
    
            public void setsYear(int sYear) {
                this.sYear = sYear;
            }
    
            public int getsMonth() {
                return sMonth;
            }
    
            public void setsMonth(int sMonth) {
                this.sMonth = sMonth;
            }
    
            public int getsDay() {
                return sDay;
            }
    
            public void setsDay(int sDay) {
                this.sDay = sDay;
            }
    
            public char getWeek() {
                return week;
            }
    
            public void setWeek(char week) {
                this.week = week;
            }
    
            public int getlYear() {
                return lYear;
            }
    
            public void setlYear(int lYear) {
                this.lYear = lYear;
            }
    
            public int getlMonth() {
                return lMonth;
            }
    
            public void setlMonth(int lMonth) {
                this.lMonth = lMonth;
            }
    
            public int getlDay() {
                return lDay;
            }
    
            public void setlDay(int lDay) {
                this.lDay = lDay;
            }
    
            public boolean isLeap() {
                return isLeap;
            }
    
            public void setLeap(boolean leap) {
                isLeap = leap;
            }
    
            public String getcYear() {
                return cYear;
            }
    
            public void setcYear(String cYear) {
                this.cYear = cYear;
            }
    
            public String getcMonth() {
                return cMonth;
            }
    
            public void setcMonth(String cMonth) {
                this.cMonth = cMonth;
            }
    
            public String getcDay() {
                return cDay;
            }
    
            public void setcDay(String cDay) {
                this.cDay = cDay;
            }
    
            public String getColor() {
                return color;
            }
    
            public void setColor(String color) {
                this.color = color;
            }
    
            public boolean isToday() {
                return isToday;
            }
    
            public void setToday(boolean today) {
                isToday = today;
            }
    
            public String getLunarFestival() {
                return lunarFestival;
            }
    
            public void setLunarFestival(String lunarFestival) {
                this.lunarFestival = lunarFestival;
            }
    
            public String getSolarFestival() {
                return solarFestival;
            }
    
            public void setSolarFestival(String solarFestival) {
                this.solarFestival = solarFestival;
            }
    
            public String getSolarTerms() {
                return solarTerms;
            }
    
            public void setSolarTerms(String solarTerms) {
                this.solarTerms = solarTerms;
            }
    
            public String getlMonthChinese() {
                return lMonthChinese;
            }
    
            public void setlMonthChinese(String lMonthChinese) {
                this.lMonthChinese = lMonthChinese;
            }
    
            public String getlDayChinese() {
                return lDayChinese;
            }
    
            public void setlDayChinese(String lDayChinese) {
                this.lDayChinese = lDayChinese;
            }
        }
    
    
    }
    复制代码

    使用

         SimpleCalendar.Element element = SimpleCalendar.getCalendarDetail(date);
    复制代码
    {
        "sYear": 2019,
        "sMonth": 5,
        "sDay": 1,
        "week": "三",
        "lYear": 2019,
        "lMonth": 3,
        "lDay": 27,
        "cYear": "己亥",
        "cMonth": "戊辰",
        "cDay": "廿七",
        "color": "",
        "lunarFestival": "",
        "solarFestival": "国际劳动节",
        "solarTerms": "",
        "sgz5": "<FONT color=#0000A0>日值月破 大事不宜</font>",
        "sgz3": "破",
        "leap": false,
        "today": false
    }
    复制代码

    通过修改以下js源码实现

    注:maozedong诞辰 关键字不能上传改为** 自行替换 

     
    标签: java后端工具 

    ——————————————————————————————————————————————————————————————————————————————————————————————


    为什么会有闰年和闰月,看了这篇文章就明白了
    https://baijiahao.baidu.com/s?id=1669848806923104758&wfr=spider&for=pc

    科普:闰月是什么意思呢?
    https://www.sohu.com/a/159571430_275723

    科普:闰月是什么意思呢? 

    我们国家是一个上下五千年,历史悠久的一个国家,我们国家文化的发展也是一个十分健全的,我们国家现在使用两种历法,

    一种是世界通用的公历,另外一种是我们国家文化的精髓,农历,农历有的时候会出现一年13个月,

    有一个重复月份,被称为闰月,那么闰月是什么意思,闰月是怎么回事,下面就由天气网万年历频道小编来为大家解答解答。

    闰月是什么意思?

    就是那年有俩个同一月数。比如某年是闰四月就是那年有两个四月。但是农历的四月有两个不影响阴历的月份,阴历的月份还是照常算。

    闰月是怎么回事?

    闰月(Leap Month),是一种历法置闰方式。在亚洲(尤其在中国),闰月特指汉历(民间亦称农历)每逢闰年增加的一个月(为了协调回归年与汉历年的矛盾,防止汉历年月与回归年及四季脱节,每2至3年置1闰,古代曾采用19年置7闰的闰周,到唐代的《麟德历》时废除了固定闰周,采用无中气月置闰,因此是该闰时置闰)。有时,闰月也指公历的闰年中包含闰日的月份(特指公历闰年的二月)。

    闰月,是阴阳历中为使历年平均长度接近回归年而增设的月和日。

    阴阳历以朔望月的长度(29.5306日)为一个月的平均值,全年12个月,同回归年(365.2422日)相差约10日21时,故需要置闰,古时曾采用:三年闰一个月,五年闰二个月,十九年闰七个月。闰月加在某月之后叫“闰某月”,如已经过去的公历2009年对应汉历闰月为己丑年闰五月(公历2009年6月23日—2009年7月21日),又如公历2012年对用汉历闰月为的壬辰年闰四月(公历2012年5月21日—2012年6月18日),又如公历2014年对用汉历闰月为的甲午年闰九月(公历2014年10月24日—2014年11月21日)等。

    闰月的诞生也是通过我们的先祖们才产生的一种计算方式,闰月的计算方式也是一个十分容易的方式,是千家万户自己都可以简单的算出来的日子,对我们现代来说是没有特别大的作用,但是在多年前,这个历法是十分重要的!

    ————————————————————————————————————————————————————————————————————————————————————————————

    为什么会有闰年和闰月,看了这篇文章就明白了?

    古时候人们由于没有手机,也不能看电视,所以吃饱了没事干就喜欢观察天空。他们发现,天空中太阳月亮和星星每隔一段时间就会东升西落一次,就把这一段时间规定为一天。而月亮的圆缺程度每天也不一样,大约29天多的时间就会形成一个循环,所以就把月亮圆缺变化的周期规定为一个月。太阳每天的倾斜角度也不一样,大约365天多就能循环一次,所以把这段时间又规定为一年。

    365除以29等于12.586并不是一个整数,比12要多比13要少,那么一年到底应该是多少个月呢?在处理这个问题上,产生了分歧,不同的国家采用了不同的标准,也就产生了不同的历法。

    欧美人的祖先用简单粗暴的方法解决这个矛盾。不管月亮的圆缺如何变化,把一年的365天分成12份,每份就是一个月。其中1月3月5月7月8月10月12月给分了31天,4月6月9月11月给分了30天,倒霉的2月就只有28天。这样加起来刚好是365天。用了一段时间发现不对头,太阳回归的时间越来越向后推,这是因为太阳的回归年并不是准确的365天而是365.2422天。于是就用闰年的办法加以修正,每四年来一个闰年,每到100年的整数倍的时候又不闰年,400年的整数倍的时候又闰年。闰年的时候就在2月份的时候加1天变成29天。这样修正再修正,误差确实是少了,不过还是有误差,经过3333年会错一天。而欧美人对这个误差并不理会了,反正3000多年后的事情交给后代去处理吧。

    欧美人的这种历法就是公历,按历法性质看是一种阳历,是按太阳的回归划分时间阶段的。这样做的好处是每天的时间,每月的时间都大致平均了,地球公转引起的四季变化也规律非常确定,更方便日常生活的使用。不好的地方是,放弃了月亮的圆缺变化规律,导致月亮的圆缺变化跟公历对不上。随月亮一起来的潮汐规律跟公历也对不上。

    中国的祖先在处理这个问题的时候就谨慎很多。中国传统的农历,把月亮圆缺变化的周期29.53059天规定为一个月,即是一个朔望月。为了取整,把月份分成了大月和小月,大月30天小月29天。一个29一个30其实还是少了0.03059天的,别急,中国古人并不会把它忽略掉,而是继续向后累加,直到累加够一天的时候就再多一个大月出来,剩余的部分继续累加。太阳的一个回归年是365.244天,月亮的望朔月是29.53059天也不是整数关系,我们的先人就想到了一个19年7闰的办法加以修正,就是每19年中刚好会多出7个闰月。像今年就是闰4月,过了农历4月是农历的闰4月,过了闰4月才是五月。这样每百年修正一次历法,就可以保证跟回归年没有误差。这样的历法,月相变化的规律对应的很准确,都是初一或初二时新月,十五或者十六时满月,用二十四节气推演四季的变化也是准确无误。中国这样太阳和月亮结合考虑制定的历法其实属于阴阳历,为了跟世界通用的公历阳历做对比,我们平时生活中也叫做阴历。

     
  • 相关阅读:
    技术人员转型秘笈
    2007 Office System Beta2 Technical Refresh 下载
    使用Word 2007写blog
    SharePoint WebPart 用户控件包装器 HandsOn Labs
    将Office SharePoint Server 2007 Beta2安装到DC上
    Visual Studio Tools for Office “v3” CTP!
    QuickPart : 用户控件包装器 for SharePoint 2007
    Office SharePoint Server 2007 !
    说说ASP.NET 2.0的书
    闫辉的书:《程序员,建立你的商业意识》
  • 原文地址:https://www.cnblogs.com/kelelipeng/p/15923180.html
Copyright © 2020-2023  润新知