SOURCE

console 命令行工具 X clear

                    
>
console
/**
 * @author-dorseyCh  1092240376@qq.com;
 * @my-personal-card  Chasing Dream.
 * I'm from China,I love my country and our mother language,so all of my functions explain were use Chinese!
 * */
; (function (win) { //前面这分号别去掉哦,防止多个js文件合并压缩时因上一个js文件末尾少";"而带来的问题。

    "use strict"; //严格模式,一般写自己类库的时候最好加上,减少一些代码不规范引起的错误。

    /**
     * 模块说明:dorseyUI作为一切处理函数的入口,需要注意的是部分函数调用到dorseyHf函数处理,故而需要引入dorsey-handle-function文件,
     *           且该文件的位置需要放置在dorsey-ui.js之前。
     * */
    var dc_self;
    var dorseyUI = function () {
        return new dorseyUI.fn.init();
    };
    function countBits(u) {
        // https://blogs.msdn.microsoft.com/jeuge/2005/06/08/bit-fiddling-3/
        const uCount = u - (u >> 1 & 0o33333333333) - (u >> 2 & 0o11111111111);
        return (uCount + (uCount >> 3) & 0o30707070707) % 63;
    }
    dorseyUI.fn = dorseyUI.prototype = {
        constructor: dorseyUI, //接口名:是dorsey-ui的缩写。意为函数处理
        init() {
            dc_self = this;
            return this;
        },
        /*组件1、万年历*/
        dcCalendar(obj) {
            /**
             *  创建日历对象
             * */
            var calendar = {
                /**
                 *  农历数据
                 * */
                lunarData: [
                    0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2,//1900-1909
                    0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977,//1910-1919
                    0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970,//1920-1929
                    0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950,//1930-1939
                    0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557,//1940-1949
                    0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0,//1950-1959
                    0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0,//1960-1969
                    0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6,//1970-1979
                    0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570,//1980-1989
                    0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0,//1990-1999
                    0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5,//2000-2009
                    0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930,//2010-2019
                    0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530,//2020-2029
                    0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45,//2030-2039
                    0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0,//2040-2049
                    0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0,//2050-2059
                    0x0a2e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4,//2060-2069
                    0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0,//2070-2079
                    0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160,//2080-2089
                    0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252,//2090-2099
                    0x0d520],//2100
                lunarYearOffset: [],
                /**
                 *  二十四节气数据
                 * */
                sTermDate: [
                    0, 21208, 42467, 63836, 85337, 107014,
                    128867, 150921, 173149, 195551, 218072, 240693,
                    263343, 285989, 308563, 331033, 353350, 375494,
                    397447, 419210, 440795, 462224, 483532, 504758
                ],
                /**
                 *  二十四节气——中文
                 * */
                sTermChinese: [
                    "立春", "雨水", "惊蛰", "春分", "清明", "谷雨",
                    "立夏", "小满", "芒种", "夏至", "小暑", "大暑",
                    "立秋", "处暑", "白露", "秋分", "寒露", "霜降",
                    "立冬", "小雪", "大雪", "冬至", "小寒", "大寒"
                ],
                /**
                 *  阳历节日对象——中文
                 * */
                festivalChinese: {
                    //第一季度
                    "0101": "元旦",
                    "0214": "情人节",
                    "0308": "妇女节",
                    "0312": "植树节",
                    "0315": "消费者权益日",
                    "0321": "世界森林日、世界儿歌日",

                    //第二季度
                    "0401": "愚人节",
                    "0407": "世界卫生日",
                    "0422": "世界地球日",
                    "0501": "劳动节",
                    "0504": "青年节",
                    "0505": "碘缺乏病防治日",
                    "0508": "世界红十字日",
                    "0512": "国际护士节",
                    "0515": "国际家庭日",
                    "0517": "世界电信日",
                    "0518": "国际博物馆日",
                    "0520": "520情人节",
                    "0523": "国际牛奶日",
                    "0531": "世界无烟日",
                    "0601": "儿童节",
                    "0605": "世界环境日",
                    "0606": "全国爱眼日",
                    "0616": "防治荒漠化和干旱日",
                    "0623": "国际奥林匹克日",
                    "0625": "全国土地日",
                    "0626": "国际反毒品日",

                    //第三季度
                    "0701": "建党节 香港回归纪念 国际建筑日",
                    "0707": "中国人民抗日战争纪念日",
                    "0711": "世界人口日",
                    "0801": "建军节",
                    "0908": "国际扫盲日",
                    "0909": "毛泽东逝世纪念",
                    "0910": "教师节",
                    "0916": "国际臭氧层保护日",
                    "0920": "国际爱牙日",
                    "0927": "世界旅游日",
                    "0928": "孔子诞辰",

                    //第四季度
                    "1001": "国庆节 国际音乐日",
                    "1004": "世界动物日",
                    "1006": "老人节",
                    "1008": "全国高血压日 世界视觉日",
                    "1009": "世界邮政日",
                    "1015": "国际盲人节",
                    "1016": "世界粮食日",
                    "1017": "世界消除贫困日",
                    "1024": "联合国日",
                    "1108": "中国记者日",
                    "1109": "消防宣传日",
                    "1112": "孙中山诞辰纪念",
                    "1114": "世界糖尿病日",
                    "1117": "国际大学生节",
                    "1201": "世界艾滋病日",
                    "1203": "世界残疾人日",
                    "1209": "世界足球日",
                    "1220": "澳门回归纪念",
                    "1225": "圣诞节",
                    "1226": "毛泽东诞辰纪念",
                    "1229": "国际生物多样性日"
                },
                /**
                 *  农历节日对象——中文
                 * */
                lFestivalChinese: {
                    "0101": "春节",
                    "0202": "头牙",
                    "0115": "元宵节",
                    "0505": "端午节",
                    "0707": "七巧节",
                    "0715": "中元节",
                    "0815": "中秋节",
                    "0909": "重阳节",
                    "1208": "腊八节",
                    "1216": "尾牙",
                    "1223": "小年",
                    "0100": "除夕"
                },
                /**
                 *  农历日十位
                 * */
                lDecade: ["初", "初", "十", "二", "廿", "三"],
                /**
                 *  农历日各位
                 * */
                lDate: ["十", "一", "二", "三", "四", "五", "六", "七", "八", "九"],
                /**
                 *  农历月
                 * */
                lMonthArr: ["正", "二", "三", "四", "五", "六", "七", "八", "九", "十", "冬", "腊"],
                /**
                 *  十天干
                 * */
                heavenlyStems: ["甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"],
                /**
                 *  十二地支:分别对应十二时辰
                 * */
                terrestrialBranch: ["子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"],
                /**
                 *  十二生肖
                 * */
                animals: ["鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪"],
                /**
                 *  用一个函数继承下时间函数
                 * */
                dateFunction() {
                    return new Date();
                },
                /**
                 *  返回当前时间数组
                 *  @example:console.log(this.thisTime()); //当前时间函数
                 * */
                thisTime() {
                    var _self = this;
                    var year = _self.dateFunction().getFullYear(),//获取年
                        month = _self.dateFunction().getMonth(),//获取月
                        today = _self.dateFunction().getDate(),//获取日
                        weekNum = _self.dateFunction().getDay(),//获取星期
                        hour = _self.dateFunction().getHours(),//获取小时
                        minute = _self.dateFunction().getMinutes(),//获取分钟
                        second = _self.dateFunction().getSeconds();//获取秒
                    return [year, month, today, weekNum, hour, minute, second]; //返回所需数据
                },
                /**
                 *  公历(阳历)相关函数
                 *
                 *  1、返回该年是否是闰年,是返回1,不是返回0
                 *  @example:console.log(this.isLeapYear(2100));//0
                 * */
                isLeapYear(year) {
                    return 0 + (year % 4 === 0 && year % 100 !== 0 || year % 400 === 0) //闰年处理
                },
                monthDates(y) {
                    return [31, 28 + this.isLeapYear(y), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
                },
                week: ['日', '一', '二', '三', '四', '五', '六'],
                /**
                 *  农历(阴历)相关函数
                 *
                 *  1、解析农历数据,返回一个二进制对象
                 * */
                lunarTran(y) {

                    var lunarData = this.lunarData[y - 1900];

                    var hexadecimal = lunarData.toString(16),
                        head = Math.floor(lunarData / 65536).toString(2), //头部说明闰月是大月还是小月
                        center = Math.floor((lunarData % 65536) / 16).toString(2),//中部说明哪个月是大月哪个是小月的二进制数
                        end = lunarData % 16; //尾部说明哪个月是闰月,没有闰月则为0
                    //字符串补全处理
                    if (center.length < 12) {
                        var i = 12 - center.length;
                        while (i--) {
                            center = "0" + center;
                        }
                    }
                    hexadecimal.length !== 5 ? hexadecimal = "0x0" + hexadecimal : hexadecimal = "0x" + hexadecimal;//16进制数
                    var bigMonthNum = (center + head).match(new RegExp('1', 'g')).length,//输出大月个数
                        monthDetail = center.split(''); //把二进制整合成一个数组

                    end !== 0 ? monthDetail.splice(end, 0, head) : end; //把尾部是否为闰月的月份插回去

                    var everyMonthDays = []; //用于输出每一年所有月份的天数,包括闰月
                    for (var i = 0; i < monthDetail.length; i++) {
                        if (monthDetail[i] === "1") {
                            everyMonthDays.push(30);
                        }
                        else {
                            everyMonthDays.push(29);
                        }
                    }
                    return {
                        thisYear: y,   //这一年是哪一年
                        lunarData: hexadecimal, //该年的农历数据,16进制的数据,即我们上面那个数据表,如:ox04bd8
                        isBigLeadMonth: parseInt(head), //头部数据,表示闰月是否为大月,是为1,否为0,没有闰月则返回0
                        monthBinaryData: center, //中部数据,2进制数据,为除了闰月其他1-12月的月份是否为大月,如:010010111101 表示1月是29天,2月是30天,依次类推
                        monthDetail: monthDetail, //月份详情,返回一个数组,若有闰月则自动添加进对应的月份之后。
                        everyMonthDays: everyMonthDays, //返回一年中所有月份的天数包括闰月
                        bigMonthNum: bigMonthNum, //这一年里大月(30天)的数量
                        whichIsLeadMonth: end //尾部数据,返回若是闰月,是哪个月为闰月
                    };
                },
                /*
                * 2、输入一个数,返回农历值,比如:输入 20 返回 廿十 ,输入1 返回初一
                * @example: console.log(this.numToLunar(20)) //"廿十"
                * */
                numToLunar(num) {
                    return this.lDecade[(num / 10 | 0) * 2 - (num % 10 === 0)] + this.lDate[num % 10];
                },
                /**
                 *  3、解析农历数据,返回某一年的总农历天数
                 *  @example : console.log(this.daysInYear(1900)); //384
                 * */
                daysInYear: function (y) {
                    var obj = this.lunarTran(y);
                    return obj.monthDetail.length * 29 + obj.bigMonthNum;
                },
                /**
                 *  4、解析农历数据,返回某一年某一月总农历天数
                 *     闰年多出的那一个月这里暂时不管,因为上面已有一个封好的对象,到时转化时直接调用即可
                 *  @example:console.log(this.daysInMonth(2018,7)); //30//代表2018年农历7月份有30天
                 * */
                daysInMonth: function (y, m) {
                    return (this.lunarData[y - 1900] & (0x10000 >> (m + 1))) ? 30 : 29;
                },
                /**
                 *  5、返回任意月上个月的农历天数,包括上一年的闰12月也都可以,当然了,一年里两个12月的上面的数据好像是没有的,不过呢
                 *     这种情况咱还是要考虑进去哈,既然是程序公式嘛肯定得通用,考虑所有可能出现的情况。
                 *     为什么要做这个?因为我们后面得到的偏移量有正也有负,正值好办,但负值我们需要知道上个月的天数
                 *
                 *     console.log("本月:"+this.daysInPreMonth(2078,1)); //这两者的返回值相同 这里的2078,1是指2078年第一个农历月
                 *     console.log("上个月:"+this.daysInMonth(2077,12)); //这里跟上面的也是一样的
                 * */
                daysInPreMonth: function (y, m) {
                    var _self = this,
                        obj = _self.lunarTran(y);  //获取今年日历对象
                    var days;

                    //分两种情况进行讨论,上个月在今年跟上个月在上一年
                    if (m > 0) {
                        if (obj.isBigLeadMonth === "1" && m === obj.whichIsLeadMonth + 1) { //如果该年是闰年且m为闰年后第一个月,则
                            return (obj.isBigLeadMonth === 0 ? 29 : 30);
                        }
                        else {
                            return _self.daysInMonth(y, m - 1);
                        }
                    }
                    else {
                        var objPre = _self.lunarTran(y - 1); //获取上一年日历对象
                        return objPre.everyMonthDays[objPre.everyMonthDays.length - 1];
                    }
                    //上面的比较啰嗦,这是简化版,你把这里注释掉用上面的也是可以哈,相对比较直观明了。
                    // m > 0 ? ((obj.isBigLeadMonth === "1" && m === obj.whichIsLeadMonth+1)? days =(obj.isBigLeadMonth === 0 ? 29 : 30) :
                    //     days =_self.daysInMonth(y,m-1)) : days = objPre.everyMonthDays[objPre.everyMonthDays.length-1];
                    //
                    // return days;
                },
                /**
                 *  6、通过1900年1月31日确定公历每年的第一天也就是xx年1月1日的农历偏移量
                 *  @example :
                 *  for(var i = 1900;i<2100;i++){
                 *      console.log(this.lFirstDayInEveryYears(i));
                 *  }
                 * */
                lFirstDayInEveryYears: function (y) {
                    var _self = this;
                    //我们需要计算任意一天距离1900年1月31日的偏移量,单位(天);
                    var baseDate = new Date(1900, 0, 31).getTime(),
                        offset = Math.floor((new Date(y, 0, 1).getTime() - baseDate) / 86400000),//计算偏移量
                        mOffset = 2;//月份偏移量:比如说1月1号是落在农历的11月份还是12月份
                    if (y === 1900) {
                        offset = 0;
                        mOffset = 1;
                    }
                    else {
                        for (var i = 1900; i < y; i++) {
                            offset -= _self.daysInYear(i);
                        }
                        /**
                         *  这里呢,为了简化算法,咱用了点取巧的方式,我们通过查询万年历可以得知农历的正月初一不会出现在元旦(1月1号)之前,
                         * */
                        //也不会出现在3月之后,这就给我们的算法提供了方便,当然啦,其实这种方式呢我虽然这么做了,但我个人的鄙视的= =,假如
                        // 说农历的正月初一出现在三月或者春节之前,那我们这算法就废了,当然了,这种情况不可能。
                        if (offset < 0) {
                            // //这里呢,咱防一手闰12月的哈,实际上是没有这个可能的,不过这样的程序看起来比较严谨一点
                            if ((_self.lunarTran(y).lunarData & 0x0000c) === 12) {
                                // console.log("if-if,my name is ChenDuoXin,my English name is dorseyCh.");
                                offset += (_self.daysInPreMonth(y, 0) + _self.daysInMonth(y - 1, 11));
                            }
                            else {
                                offset += _self.daysInPreMonth(y, 0);
                                offset < 0 ? offset += _self.daysInPreMonth(y - 1, 11) : mOffset = 1;
                            }
                        }
                    }
                    return {
                        thisYear: y,
                        offset: offset,
                        mOffset: mOffset
                    };
                },
                /**
                 *  7、输入y年m月,输出这个月1号的偏移量,或者说是农历值(阳历转农历)
                 *
                 *  1900年1月31日正好对应农历的正月初一。
                 *
                 *  输入y年m月,输出这个月1号的偏移量,或者说是农历值,思路非常简单,到这一步的时候我们知道什么呢?
                 *  知道每一年1月1号所对应的农历值对吧?然后要到每一个月,但是呢,阳历的月份跟农历的月份天数是不对应的,所以还
                 *  需要做下面的事:
                 *      1、计算当前阳历时间距离同年1月1号的天数间隔
                 *      2、我们知道每一年1月1号这一天是已经跟农历对照好了的。
                 *      3、知道了这个间隔,那我们就可以推出:过了这个间隔之后,农历的偏移量做了多少的改变
                 * */
                solarToLunar: function (y, m) {

                    var _self = this;
                    // console.log(y+"年"+(m+1)+"月1日");
                    //年份的我们可以不用管,但月份的需要知道一个,什么呢?就是你想输入的那个月的前面的月份可能会有包含一个闰月
                    var offsetObj = _self.lFirstDayInEveryYears(y),//获取当年阳历1月1号所对应的农历值,包括日偏移与月偏移
                        obj = _self.lunarTran(y),
                        monthDates = this.monthDates(y),
                        offset = offsetObj.offset;
                    //计算每个月1号的偏移量
                    if (y === 1900) {
                        for (var i = 0; i < m; i++) {
                            i < 1 ? offset += monthDates[i] - 30 : offset += monthDates[i] - obj.everyMonthDays[i - 1];
                        }
                    }
                    else {
                        var objPre = _self.lunarTran(y - 1);
                        for (var i = 0; i < m; i++) {
                            if (i < offsetObj.mOffset) {
                                offset += (monthDates[i] - objPre.everyMonthDays[objPre.everyMonthDays.length - 1 - i]);
                            }
                            else {
                                offset += (monthDates[i] - obj.everyMonthDays[i - offsetObj.mOffset]);
                            }
                        }
                    }
                    return [offset, offsetObj.mOffset];
                },
                /**
                 *  8、通过世界时以及节气年返回year年第n个节气所对应为该月第几天
                 *  31556925974.7:是一个节气年,24个节气合起来总计多少ms。
                 *  Date.UTC(1900,0,6,2,5):1900年1月6日2时5分为小寒节气开始,从这里开始,记得是以小寒开始,且历法的精确度仅仅到分钟
                 *  @example : console.log(this.sTermToDate(2018, 2)); //2018立春是月份的4号,打印出了4
                 **/
                sTermToDate: function (year, n) {
                    var offDate = new Date((31556925974.7 * (year - 1900) + this.sTermDate[n] * 60000)
                        + Date.UTC(1900, 0, 6, 2, 5));
                    return (offDate.getUTCDate());
                },
                init() {
                    let start = new Date(1900, 0, 31) // 1900年元月一日

                    for (let i = 0; i < 200; ++i) {
                        this.lunarYearOffset.push(new Date(start)) // 返回每年农历元月一日的公历日期
                        const calendar = this.lunarData[i]
                        const days = (12 + ((calendar & 0xf) > 0)) * 29 + countBits(calendar >> 4)
                        start.setDate(start.getDate() + days)
                    }
                },
                // leap year, month in [0, 12] 
                // not leap year, month in [0, 11]
                lunarDaysOfMonth(year, lmonth) {
                    return (this.monthData(year) & (1 << lmonth)) > 0 ? 30 : 29
                },
                lunarYearDays(year, lmonth) {
                    return countBits(this.monthData(year) & ((1 << lmonth) - 1)) + lmonth * 29
                },
                lunarDate(date) {
                    let year = date.getFullYear()
                    let base = this.lunarYearOffset[year - 1900]
                    // 日期是前一个农历年
                    if (date < base) {
                        year -= 1
                        base = this.lunarYearOffset[year - 1900]
                    }
                    let yearData = this.lunarData[year - 1900]
                    let ldate = (date - base) / (60 * 60 * 24 * 1000) | 0

                    let lmonth = (ldate / 30 | 0)
                    ldate -= this.lunarYearDays(year, lmonth)
                    let nextMonth = this.lunarDaysOfMonth(year, lmonth + 1)
                    if (ldate > nextMonth) {
                        ldate -= nextMonth
                        ++lmonth
                    }
                    return { year, lmonth, ldate, leap: yearData & 0xf }
                },
                monthList(year) {
                    let yearData = this.lunarData[year - 1900]
                    let months = (yearData >> 4 | 0x1000).toString(2).split('')
                        .slice(1).reverse().map(x => +x + 29)
                    // 插入闰月
                    if ((yearData & 0xf) > 0) {
                        months.splice(yearData & 0xf, 0, yearData >> 16)
                    }
                    return months
                },
                monthData(year) {
                    const yearData = this.lunarData[year - 1900]
                    const leap = yearData & 0xf
                    if (leap === 0) {
                        return yearData >> 4
                    }
                    const mask = (1 << leap) - 1
                    return (yearData >> 4 & mask) |
                        (yearData >> 16 << leap) |
                        (yearData >> 4 + leap << leap + 1)
                },
                toDate(lunarDate) {
                    const year = lunarDate.year
                    let date = new Date(this.lunarYearOffset[year - 1900])
                    let days = lunarDate.ldate + date.getDate() +
                        this.lunarYearDays(year, lunarDate.lmonth)

                    date.setDate(days)
                    return date
                },

                /**
                 *  测试函数
                 * */
                test() {
                    this.init()
                    //console.log(this.lunarYearOffset)
                    console.log(this.lunarYearOffset[0], this.lunarYearOffset[1])
                    console.log(this.thisTime()); //当前时间函数
                    console.log(this.lunarDate(new Date(2020, 7, 1)))
                    console.log(this.monthList(2020))
                    console.log(this.toDate(this.lunarDate(new Date(2020, 0, 24))))
                    /**
                     *  公历相关
                     * */
                    console.log(this.isLeapYear(2100)); //判断该年是否是闰年

                    /**
                     *  农历相关
                     * */
                    console.log(this.numToLunar(19)); //数据转农历中文日期
                    console.log(this.lunarTran(2017)); //农历数据解析函数,返回一个二进制对象
                    console.log(this.daysInYear(1900)); //返回该年的农历总天数
                    console.log(this.sTermToDate(2018, 2)); //2018立春是月份的4号,打印出了4
                    // for (var i = 1900; i < 2100; i++) {  //返回每一年1月1号的偏移量
                    //     console.log(this.lFirstDayInEveryYears(i), this.lunarYearOffset[i-1900]);

                    // }
                    this.solarToLunar(2017, 3); //初五
                    this.solarToLunar(1900, 3);//1900比较特殊因为它是最前面,没有上一年
                    // for (var i = 0; i < 12; i++) {
                    //     console.log(this.solarToLunar(2018, i));
                    // }
                    console.log("本月1:" + this.daysInPreMonth(2017, 0));
                    console.log("本月2:" + this.daysInPreMonth(2017, 0) + "上个月1:" + this.daysInMonth(2016, 12));
                }
            };
            calendar.test();
            /**
             *  日历开始
             * */

            var thisTime = calendar.thisTime(),
                rel, detailX, detailY,
                year = thisTime[0],
                month = thisTime[1],
                today = thisTime[2],
                weekNum = thisTime[3],
                week = calendar.week,
                monthDates = calendar.monthDates(year),
                lMonthArr = calendar.lMonthArr;
            /*==============================@start js日期表格创建=======================================*/
            //放置上层按钮及日期显示
            var btn = $('<div class="calendarBtn">' +
                '<span class="yBtn">-</span>' +
                '<span class="mBtn">-</span>' +
                '<div class="dcCalendarValues">' + year + '年' + (month + 1) + '月' + today + '日 <span>星期' + week[weekNum] + '</span></div>' +
                '<span class="mBtn">+</span>' +
                '<span class="yBtn">+</span>' +
                '</div>');
            obj.append(btn);
            /*放在下层的日历*/
            var table = $('<table class="calendarTable"><thead><tr><th>日</th><th>一</th><th>二</th><th>三</th><th>四</th><th>五</th><th>六</th></tr></thead>' +
                '<tbody class="calendarTbody">' +
                '<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>' +
                '<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>' +
                '<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>' +
                '<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>' +
                '<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>' +
                '<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>' +
                '</tbody></table>');
            obj.append(table);
            obj.append($('<div class="dcDateDetail"></div>'));
            /*==============================@end js日期表格创建=======================================*/
            var $tBody = $('.calendarTbody'),//万年历每张日历表的容器<tbody></tbody>
                $dateDetail = $('.dcDateDetail'),//每个日期对应的详情页,显示农历节日等等
                $CalendarValues = $('.dcCalendarValues');//日历上方当前日期简介
            /*更新函数,即无论是点击还是查看,页面的html重新写入都用这个函数*/
            var update = function () {
                var firstDay = new Date(year, month, 1),//获取每个月的第一天
                    dayOfWeek = firstDay.getDay();//这个月第一天的世界时去转换成星期几

                const lastDayOfPrevMonth = new Date(year, month, 0).getDate()
                const lastDayOfMonth = new Date(year, month + 1, 0).getDate()

                // lMonth = month-arr[1]; //农历的月份
                const lunarDate = calendar.lunarDate(firstDay)
                const lunarDaysOfMonth = calendar.lunarDaysOfMonth(lunarDate.year, lunarDate.lmonth)

                // $tBody.find('td').css("color", "").css("opacity", "");//清空原有样式
                $tBody.find('td').each(function (rel) {
                    
                    let $td = $(this).css({"color": "", "opacity": ""})
                    let date = rel - dayOfWeek + 1
                    if (date <= 0) {
                        date += lastDayOfPrevMonth
                        $td.html(date).css("opacity", "0.3");
                    } else if (date > lastDayOfMonth) {
                        date -= lastDayOfMonth
                        $td.html(date).css("opacity", "0.3");
                    } else {
                        let ldate = lunarDate.ldate + date - 1
                        if (ldate > lunarDaysOfMonth) {
                            ldate -= lunarDaysOfMonth
                        }
                        
                        $td.html("<p class='solarValue'>" + date + "</p>"
                            + "<p>" + calendar.numToLunar(ldate) + "</p>");

                        if (date === thisTime[2]) {
                            $td.css("color", "red");
                        }
                    }
                })
                
                $CalendarValues.html(year + '年' + (month + 1) + '月' + today + '日 <span class="weekAdapt">星期' + week[weekNum] + '</span>');//每次更新重写日期简介
            };
            update();//初始化
            /*4个按钮功能函数*/
            $('.calendarBtn span').click(function () {
                // console.log($(this).index());
                switch ($(this).index()) {
                    case 0: year -= 1; break;
                    case 1: {
                        month -= 1;
                        if (month < 0) { month = 11; year -= 1; }
                        break;
                    }
                    case 3: {
                        month += 1;
                        if (month > 11) { month = 0; year += 1; }
                        break;
                    }
                    case 4: year += 1; break;
                }
                update();
            });
            /*鼠标移入显示详情,移出隐藏详情*/
            $tBody.mouseover(function () {
                $dateDetail.css("display", "block");
            });
            $tBody.mouseout(function () {
                $dateDetail.css("display", "none");
            });
            /*每一天鼠标滑动显示详情*/
            $tBody.find('td').each(function () {
                $(this).mousemove(function (e) {
                    e = e || window.event;
                    detailX = e.pageX - $tBody.offset().left;
                    detailY = e.pageY - obj.offset().top;
                    $dateDetail.css({
                        left: (detailX + 30) + "px",
                        top: (detailY) + "px"
                    });
                    if ($(this).css("opacity") === "1") {
                        $CalendarValues.html(year + '年' + (month + 1) + '月' + $(this).children('.solarValue').html() + '日 <span class="weekAdapt">星期' + week[$(this).index() % 7] + '</span>');
                        $tBody.find('td').removeClass('calendarMouseMove');
                        $(this).addClass('calendarMouseMove');
                        /*================@start 阳历节日嵌入===============*/
                        var festivalDate;//阳历节日变量
                        var fm = month + 1,
                            dm = $(this).children('.solarValue').html();
                        fm < 10 ? fm = "0" + fm : fm;
                        dm < 10 ? dm = "0" + dm : dm;
                        if (calendar.festivalChinese[fm + dm] !== undefined) {
                            festivalDate = calendar.festivalChinese[fm + dm];
                        }
                        else {
                            festivalDate = "";
                        }
                        /*================@end 阳历节日嵌入===============*/
                        $dateDetail.html($CalendarValues.html() + "<p>" + festivalDate + "</p>");

                    }
                });
            });


            /*自适应判定*/
            if (obj.width() < 270) {
                obj.css("font-size", "5px");
                obj.find(".dcCalendarValues").find('span').css("display", "none");
            }
        }
    };
    dorseyUI = dorseyUI.fn.init.fn = dorseyUI.fn;
    win.dorseyUI = dorseyUI;
})(window);

$(function () {
    dorseyUI.dcCalendar($('.dcCalendarAddLunar'));
    /*万年历*/
    // dorseyUI.dcCalendar($('#dcCalendar'));
});





<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>万年历(带农历)</title>
    <style>

    </style>

</head>
<body>
<!--<div class="calendar"></div>-->

<div class="dc_calendar">
    <div class="dcCalendarAddLunar" id="dcCalendar"></div>
</div>
</body>
</html>
html,
body,
div,
ol,
ul,
li,
p,
h1,
h2,
h3,
h4,
h5,
h6,
table,
tr,
td,
dt,
dd,
span,
img {
    margin: 0;
    padding: 0
}

ul,
li {
    list-style: none
}

a {
    text-decoration: none
}

.dc_left {
    float: left
}

.dc_right {
    float: right
}

.dc_pointer {
    cursor: pointer
}

.dc_clear {
    content: "";
    display: block;
    clear: both
}

.dc_mar_bottom {
    margin-bottom: 20px
}

.dc_p_center {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto
}

.dc_c_red {
    color: #f00
}

.dc_c_aaa {
    color: #aaa
}

.dcCalendar {
    width: 100%;
    height: 100%;
    min-height: 230px;
    padding: 10px;
    box-sizing: border-box;
    position: relative;
    box-shadow: -2px 2px 10px #fff;
    -webkit-box-shadow: -2px 2px 10px #fff;
    -moz-box-shadow: -2px 2px 10px #fff;
    -o-box-shadow: -2px 2px 10px #fff
}

.dcCalendar .calendarBtn {
    width: 100%;
    height: 20%
}

.dcCalendar .calendarBtn .dcCalendarValues {
    width: 50%;
    height: 3em;
    box-shadow: -2px 2px 10px #fff;
    float: left;
    font-size: 1em;
    border-radius: 1.5em 1.5em 1.5em 1.5em;
    text-align: center;
    line-height: 3em
}

.dcCalendar .calendarBtn .mBtn,
.dcCalendar .calendarBtn .yBtn {
    text-align: center;
    float: left;
    border-radius: 50% 50% 50% 50%;
    font-size: 1em;
    box-shadow: -1px 1px 2px #fff;
    cursor: pointer;
    margin: 0 .5%
}

.dcCalendar .calendarBtn .yBtn {
    width: 13%;
    height: 3em;
    line-height: 3em
}

.dcCalendar .calendarBtn .mBtn {
    width: 10%;
    height: 2em;
    line-height: 2em;
    margin-top: .5em
}

.dcCalendar .calendarTable {
    width: 100%;
    height: 75%;
    margin-top: 5%;
    padding: 10px;
    box-sizing: border-box;
    text-align: center
}

.dcCalendar .calendarTable th {
    text-align: center
}

.dcCalendar .calendarTable td {
    cursor: pointer;
    transition: .1s
}

.dcCalendar .dcDateDetail {
    display: none;
    width: 150px;
    height: 80px;
    font: 1em "Times New Roman";
    padding: 5px;
    position: absolute;
    top: 0;
    left: 0;
    background: rgba(0, 0, 0, 0.9)
}

.dcCalendarAddLunar {
    width: 100%;
    height: 100%;
    min-height: 230px;
    padding: 10px 0;
    box-sizing: border-box;
    position: relative;
    box-shadow: -2px 2px 10px #fff;
    border-radius: 5px 5px 5px 5px;
}

.dcCalendarAddLunar .calendarBtn {
    width: 100%;
    padding: 0 2%;
    box-sizing: border-box
}

.dcCalendarAddLunar .calendarBtn .dcCalendarValues {
    width: 50%;
    height: 3em;
    float: left;
    font-size: 1em;
    text-align: center;
    line-height: 3em
}

.dcCalendarAddLunar .calendarBtn .mBtn,
.dcCalendarAddLunar .calendarBtn .yBtn {
    text-align: center;
    float: left;
    border-radius: 50% 50% 50% 50%;
    -webkit-border-radius: 50% 50% 50% 50%;
    -moz-border-radius: 50% 50% 50% 50%;
    font-size: 1em;
    box-shadow: -1px 1px 2px #fff;
    -webkit-box-shadow: -1px 1px 2px #fff;
    -moz-box-shadow: -1px 1px 2px #fff;
    -o-box-shadow: -1px 1px 2px #fff;
    cursor: pointer;
    margin: 0 .5%
}

.dcCalendarAddLunar .calendarBtn .yBtn {
    width: 13%;
    height: 3em;
    line-height: 3em
}

.dcCalendarAddLunar .calendarBtn .mBtn {
    width: 10%;
    height: 2em;
    line-height: 2em;
    margin-top: .5em
}

.dcCalendarAddLunar .calendarBtn:after {
    content: "";
    display: block;
    clear: both
}

.dcCalendarAddLunar .calendarTable {
    width: 100%;
    margin-top: 10px;
    padding: 10px;
    box-sizing: border-box;
    text-align: center
}

.dcCalendarAddLunar .calendarTable th {
    text-align: center
}

.dcCalendarAddLunar .calendarTable td {
    cursor: pointer;
    transition: .1s;
    padding: 5px 0
}

.dcCalendarAddLunar .calendarTable td p {
    font-size: .3rem
}

.dcCalendarAddLunar .calendarTable td .solarValue {
    font-size: 20px
}

.dcCalendarAddLunar .calendarTable td .lMonth {
    display: none
}

.dcCalendarAddLunar .dcDateDetail {
    display: none;
    width: 150px;
    height: 80px;
    font: 1em "Times New Roman";
    padding: 5px;
    position: absolute;
    top: 0;
    left: 0;
    background: rgba(0, 0, 0, 0.9)
}

.calendarMouseMove {
    box-shadow: -1px 1px 5px #fff;
    -webkit-box-shadow: -1px 1px 5px #fff;
    -moz-box-shadow: -1px 1px 5px #fff;
    -o-box-shadow: -1px 1px 5px #fff;
    transform: translate3d(2px, -2px, 0)
}

.dcCalendar:after {
    content: "";
    display: block;
    clear: both
}

.dcAccordion {
    background: linear-gradient(#1d1d1d, #35ff10);
    width: 100%;
    text-align: center;
    font: 18px "华文楷体";
    line-height: 40px
}

.dcAccordion a {
    width: 100%;
    display: inline-block;
    color: #fff
}

.dcAccordion li ul {
    font: 12px "微软雅黑";
    line-height: 30px;
    height: 0;
    overflow: hidden;
    background: rgba(255, 255, 255, 0.2);
    transition: all .3s
}

.dcAccordion a:hover {
    background: rgba(255, 255, 255, 0.3)
}

.dcAccordionAddAnimate {
    background: linear-gradient(#1d1d1d, #35ff10);
    width: 100%;
    text-align: center;
    font: 18px "华文楷体";
    line-height: 40px
}

.dcAccordionAddAnimate a {
    width: 100%;
    display: inline-block;
    color: #fff
}

.dcAccordionAddAnimate li ul {
    font: 12px "微软雅黑";
    line-height: 30px;
    height: 0;
    overflow: hidden;
    background: rgba(255, 255, 255, 0.2);
    transition: all .3s
}

.dcAccordionAddAnimate a:hover {
    background: rgba(255, 255, 255, 0.3)
}

body {
    background: linear-gradient(to left, #56655f, #000000);
}

.dc_calendar {
    width: 450px;
    height: 450px;
    margin: 50px auto 0;
    color: #ccc;
}

本项目引用的自定义外部资源