zoukankan      html  css  js  c++  java
  • 小程序手写 的选择日期 区间

    参考: https://www.cnblogs.com/bin521/p/10244502.html 

    项目中实践

    js

    // plugin/components/calendar/calendar.js
    /**
     * 属性:
     * 01、year:年份:整型
     * 02、month:月份:整型
     * 03、day:日期:整型
     * 04、startDate:日历起点:字符串[YYYY-MM]
     * 05、endDate:日历终点:字符串[YYYY-MM]
     * 06、header:是否显示标题:布尔型
     * 07、next:是否显示下个月按钮:布尔型
     * 08、prev:是否显示上个月按钮:布尔型
     * 09、weeks:是否显示周标题:布尔型
     * 10、showMoreDays:是否显示上下月份的数字:布尔型
     * 11、lunar:是否显示农历 布尔型
     * 11、weeksType:周标题类型:字符串[en、full-en、cn]
     * 12、cellSize: 单元格大小 整型
     * 13、daysColor:设置日期字体、背景颜色
     * 14、activeType: 日期背景效果(正方形、圆形)[rounded, square]
     * 
     * 事件方法:
     * 1、nextMonth:点击下个月
     * 2、prevMonth:点击上个月
     * 3、dateChange: 日期选择器变化
     * 
     * 样式:
     * calendar-style 日历整体样式
     * header-style 标题样式
     * board-style 面板样式
     */
    
    const lunar = require('./lunar.js');
    const minYear = 1900;
    const maxYear = 2099;
    
    let dateStart, dateEnd;
    
    Component({
      /**
       * 组件的属性列表
       */
      properties: {
        /**
         * 年份
         */
        year: {
          type: Number,
          value: new Date().getFullYear(),
          observer: '_yearChange'
        },
    
        /**
         * 月份1~12
         */
        month: {
          type: Number,
          value: new Date().getMonth() + 1,
          observer: '_monthChange'
        },
    
        /**
         * 日期
         */
        day: {
          type: Number,
          value: new Date().getDate(),
          observer: '_dayChange'
        },
    
        /**
         * 日历范围起点
         */
        startDate: {
          type: String,
          value: '1900-01-01',
          observer: '_setStartDate'
        },
    
        /**
         * 日历范围终点
         */
        endDate: {
          type: String,
          value: '2099-12',
          observer: '_setEndDate'
        },
    
        /**
         * 是否显示标题
         */
        header: {
          type: Boolean,
          value: true,
          observer: '_headerChange'
        },
    
        /**
         * 是否显示下个月按钮
         */
        next: {
          type: Boolean,
          value: true
        },
    
        /**
         * 是否显示上个月按钮
         */
        prev: {
          type: Boolean,
          value: true
        },
    
        /**
         * 显示额外上下月份日期
         */
        showMoreDays: {
          type: Boolean,
          value: false,
          observer: '_moreChange'
        },
    
        /**
         * 是否显示周标题
         */
        weeks: {
          type: Boolean,
          value: true,
          observer: '_showWeeksChange'
        },
    
        /**
         * 周标题类型
         */
        weeksType: {
          type: String,
          value: 'en',
          observer: '_weeksTypeChange'
        },
    
        /**
         * 设置日期字体、背景颜色
         */
        daysColor: {
          type: Array,
          value: [],
          observer: '_setDaysColor'
        },
    
        /**
         * 单元格大小
         */
        cellSize: {
          type: Number,
          value: 30,
          observer: '_setCellSize'
        },
    
        /**
         * 设置日期背景效果
         */
        activeType: {
          type: String,
          value: 'rounded',
          observer: '_setActiveType'
        },
    
        /**
         * 是否显示农历
         */
        lunar: {
          type: Boolean,
          value: false,
          observer: '_showLunar'
        },
    
        /**
         * 额外选项
         */
        addon: {
          type: String,
          value: 'none',
          observer: '_setAddon'
        },
    
        /**
         * 日期附加选项
         */
        daysAddon: {
          type: Array,
          value: [],
          observer: '_setDaysAddon'
        },
    
        moreDays: {
          type: Boolean,
          value: false,
          observer: '_setMoreDays'
        }
      },
    
      /**
       * 组件的初始数据
       */
      data: {
        days_array: [], // 日期数组
        days_color: [], // 日期字体、背景颜色数组
        days_addon: [], // 日期附件
        weekTitle: ['S', 'M', 'T', 'W', 'T', 'F', 'S'],
        max_year: 2099, // 最大年份
        max_month: 12, // 最大月份
        max_day: 31,
        min_year: 1900, // 最小年份
        min_month: 1, // 最小月份
        min_day: 1,  // 最小日期
        moreDays: false
      },
    
      /**
       * 组件的方法列表
       */
      methods: {
        /**
         * 检查年份
         */
        _checkYear: function(year) {
          if (year < minYear) {
            throw new RangeError('年份不能小于' + minYear + '年');
          } else if (year > maxYear) {
            throw new RangeError('年份不能大于' + maxYear + '年');
          }
          return true;
        },
    
        /**
         * 检查月份
         */
        _checkMonth: function(month) {
          if (month < 1) {
            throw new RangeError('月份不能小于1');
          } else if (month > 12) {
            throw new RangeError('月份不能大于12');
          }
          return true;
        },
    
        /**
         * 检查日期是否输入正确
         * @param day int 日期
         */
        _checkDay: function(day) {
          if (day < 1) {
            throw new RangeError('日期不能小于1');
          } else if (day > 31) {
            throw new RangeError('日期不能大于31');
          }
          return true;
        },
    
        /**
         * 年份属性改变
         */
        _yearChange: function(newYear, oldYear) {
          if (this._checkYear(newYear)) {
            this.setData({
              year: newYear,
              days_array: this._setCalendarData(newYear, this.data.month)
            });
          }
        },
    
        /**
         * 月份属性改变
         */
        _monthChange: function(newMonth, oldMonth) {
          if (this._checkMonth(newMonth)) {
            this.setData({
              month: newMonth,
              days_array: this._setCalendarData(this.data.year, newMonth)
            });
          }
        },
    
        /**
         * 日期属性改变
         */
        _dayChange: function(newDay, oldDay) {
          if (this._checkDay(newDay)) {
            this.setData({
              day: newDay
            });
          }
        },
    
        /**
         * 设置起始日期
         */
        _setStartDate: function(newDate, oldDate) {
          if (newDate.length <= 10 && newDate.indexOf('-') == 4) {
            const year = parseInt(newDate.split('-')[0]);
            const month = parseInt(newDate.split('-')[1]);
            const day = parseInt(newDate.split('-')[2]);
            if (!isNaN(year) && year >= minYear && !isNaN(month) && month >= 1 && month <= 12) {
              this.setData({
                startDate: newDate,
                min_year: year,
                min_month: month,
                min_day: day
              });
              this._setCalendarData();
            } else {
              throw new Error('起始日期必须是YYYY-MM-DD格式,且大于等于1900-01-01');
            }
          } else {
            throw new Error('起始日期必须是YYYY-MM-DD格式');
          }
        },
    
        /**
         * 设置结束日期
         */
        _setEndDate: function(newDate, oldDate) {
          if (newDate.length <= 10 && newDate.indexOf('-') == 4) {
            const year = parseInt(newDate.split('-')[0]);
            const month = parseInt(newDate.split('-')[1]);
            const day = parseInt(newDate.split('-')[2]);
            if (!isNaN(year) && year <= 2099 && !isNaN(month) && month >= 1 && month <= 12) {
              this.setData({
                endDate: newDate,
                max_year: year,
                max_month: month,
                max_day: day
              });
            } else {
              throw new Error('结束日期必须是YYYY-MM-DD格式,且小于等于2099-12');
            }
          } else {
            throw new Error('结束日期必须是YYYY-MM-DD格式');
          }
        },
    
        /**
         * 是否显示标题
         */
        _headerChange: function(newHeader, oldHeader) {
          this.setData({
            header: !!newHeader
          });
        },
    
        /**
         * 是否显示额外的月份日期
         */
        _moreChange: function(newMore, oldMore) {
          this.setData({
            showMoreDays: !!newMore,
            days_array: this._setCalendarData(this.data.year, this.data.month)
          });
        },
    
        /**
         * 周标题类型
         */
        _weeksTypeChange: function(newVal, oldVal) {
          switch (newVal) {
            case 'en':
              this.setData({
                weeksType: 'en',
                weekTitle: ['S', 'M', 'T', 'W', 'T', 'F', 'S']
              });
              break;
            case 'cn':
              this.setData({
                weeksType: 'cn',
                weekTitle: ['日', '一', '二', '三', '四', '五', '六']
              });
              break;
            case 'full-en':
              this.setData({
                weeksType: 'full-en',
                weekTitle: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
              });
              break;
            default:
              this.setData({
                weeksType: 'en',
                weekTitle: ['S', 'M', 'T', 'W', 'T', 'F', 'S']
              });
              break;
          }
        },
    
        /**
         * 是否显示周标题
         */
        _showWeeksChange: function(newVal, oldVal) {
          this.setData({
            weeks: !!newVal,
          });
        },
    
        /**
         * 设置单元格宽度
         */
        _setCellSize: function(newSize, oldSize) {
          this.setData({
            cellSize: newSize
          });
        },
    
        /**
         * 是否显示农历
         */
        _showLunar: function(newConfig, oldConfig) {
          this.setData({
            lunar: !!newConfig
          });
        },
    
        /**
         * 设置日期单元格字体颜色、背景
         */
        _setDaysColor: function(newDaysColor, oldDaysColor) {
          this.setData({
            days_color: newDaysColor
          }, function() {
            this.setData({
              days_array: this._setCalendarData(this.data.year, this.data.month)
            });
          });
        },
    
        /**
         * 设置日期背景效果
         */
        _setActiveType: function(newType, oldType) {
          switch (newType) {
            case 'rounded':
            case 'square':
              this.setData({
                activeType: newType
              });
              break;
            default:
              this.setData({
                activeType: 'rounded'
              });
          }
        },
    
        /**
         * 设置日历
         * @param int year 年份
         * @param int month 月份,取值1~12
         */
        _setCalendarData: function(year, month) {
          const empty_days_count = new Date(year, month - 1, 1).getDay(); // 本月第一天是周几,0是星期日,6是星期六
          let empty_days = new Array;
          const prev_month = month - 1 == 0 ? 12 : month - 1; // 上个月的月份数
          const prev_year = month - 1 == 0 ? this.data.year - 1 : this.data.year;
          /**
           * 上个月的日期
           */
          for (let i = 0; i < empty_days_count; i++) {
            empty_days.push({
              state: 'inactive',
              day: -1,
              month: prev_month,
              year: prev_year,
              info: 'prev',
              color: '#c3c6d1',
              background: 'transparent'
            });
          }
    
          /**
           * 下个月的日期
           */
          const last_day = new Date(year, month, 0); // 本月最后一天
          const days_count = last_day.getDate(); // 本月最后一天是几号
          const last_date = last_day.getDay(); // 本月最后一天是星期几
          const next_month = month + 1 == 13 ? 1 : month + 1; // 下个月的月份数
          const next_year = month + 1 == 13 ? this.data.year + 1 : this.data.year;
          let empty_days_last = new Array;
          for (let i = 0; i < 6 - last_date; i++) {
            empty_days_last.push({
              state: 'inactive',
              day: -2,
              month: next_month,
              year: next_year,
              info: 'next',
              color: '#c3c6d1',
              background: 'transparent'
            });
          }
    
          /**
           * 本月的日期
           */
          let temp = new Array;
          for (let i = 1; i <= days_count; i++) {
            temp.push({
              state: 'inactive',
              day: i,
              month: month,
              year: year,
              info: 'current',
              color: '#4a4f74',
              background: 'transparent'
            });
          }
          const days_range = temp; // 本月
          let days = empty_days.concat(days_range, empty_days_last); // 上个月 + 本月 + 下个月            
          // 如果要显示前后月份的日期
          if (this.data.showMoreDays) {
            // 显示下月的日期
            let index = days.findIndex(element => {
              return element.day == -2;
            });
            if (index != -1) {
              const length = days.length;
              const count = length - index;
              for (let i = 1; i <= count; i++) {
                days[index + i - 1].day = i;
              }
            }
    
            // 显示上月的日期
            index = days.findIndex(element => {
              return element.day == 1;
            }) - 1;
            if (index != -1) {
              const last_month_day = new Date(year, month - 1, 0).getDate();
              for (let i = 0; i <= index; i++) {
                days[i].day = last_month_day - index + i;
              }
            }
          }
    
          /**
           * 设置日期颜色、背景
           */
          for (let i = 0; i < this.data.days_color.length; i++) {
            const item = this.data.days_color[i];
            const background = item.background ? item.background : 'transparent';
            for (let j = 0; j < days.length; j++) {
              if (days[j].month == item.month && days[j].day == item.day) {
                if (item.color) {
                  days[j].color = item.color + '!important';
                }
                if (item.background) {
                  days[j].background = item.background + '!important';
                }
              }
            }
          }
    
          /**
           * 设置农历
           */
          for (let i = 0; i < days.length; i++) {
            const item = days[i];
            const solarDay = item.day;
            const solarMonth = item.month;
            const solarYear = year;
            if (solarDay > 0) {
              const lunarDate = lunar.solarToLunar(year, solarMonth, solarDay);
              days[i]['lunarMonth'] = lunarDate.monthStr;
              days[i]['lunarDay'] = lunarDate.dayStr;
              if (lunarDate.dayStr == '初一') {
                days[i]['lunarDay'] = lunarDate.monthStr;
              }
            }
          }
    
          // 设置起止日期
          for (let i = 0; i < days.length; i++) {
            if (days[i].year < this.data.min_year || 
            (days[i].year == this.data.min_year && days[i].month < this.data.min_month) ||
              (days[i].year == this.data.min_year && days[i].month == this.data.min_month && days[i].day < this.data.min_day)) {
              days[i].color = '#c3c6d1';
            }
            if (days[i].year > this.data.max_year ||
              (days[i].year == this.data.max_year && days[i].month > this.data.max_month) ||
              (days[i].year == this.data.max_year && days[i].month == this.data.max_month && days[i].day > this.data.max_day)) {
              days[i].color = '#c3c6d1';
            }
          }
    
          let days_array = new Array;
          let week = new Array;
          for (let i = 0; i < days.length; i++) {
            week.push(days[i]);
            if (i % 7 == 6) {
              days_array.push(week);
              week = new Array;
            }
          }
    
          if (week.length > 0) {
            days_array.push(week);
          }
    
          return days_array;
        },
    
        _setAddon: function(newAddon, oldAddon) {
          if (newAddon == 'none') {
            this.setData({
              lunar: false,
              daysAddon: [],
              addon: 'none'
            });
          } else if (newAddon == 'lunar') {
            this.setData({
              lunar: true,
              daysAddon: [],
              addon: 'lunar'
            });
    
          } else if (newAddon == 'custom') {
            this.setData({
              addon: 'custom',
              lunar: false,
            });
          } else if (newAddon == 'mixed') {
            this.setData({
              addon: 'mixed',
              lunar: true
            });
          }
        },
    
        /**
         * 自定义日期数组
         */
        _setDaysAddon: function(newAddon, oldAddon) {
          if (typeof(newAddon) == 'object' && newAddon instanceof Array) {
            this.setData({
              days_addon: newAddon
            });
          }
        },
    
        /**
         * 是否允许选自日期区间
         */
        _setMoreDays: function(newMore, oldMore) {
          this.setData({
            moreDays: !!newMore,
          });
        },
    
        /**
         * 点击下个月
         */
        nextMonth: function() {
          const eventDetail = {
            prevYear: this.data.year,
            prevMonth: this.data.month
          };
    
          if (this.data.month == 12) {
            this.setData({
              year: this.data.year + 1,
              month: 1
            });
          } else {
            this.setData({
              month: this.data.month + 1
            });
          }
          this.setData({
            days_array: this._setCalendarData(this.data.year, this.data.month)
          });
          eventDetail['currentYear'] = this.data.year;
          eventDetail['currentMonth'] = this.data.month;
          this.triggerEvent('nextMonth', eventDetail);
        },
    
        /**
         * 点击上个月
         */
        prevMonth: function() {
          const eventDetail = {
            prevYear: this.data.year,
            prevMonth: this.data.month
          };
    
          if (this.data.month == 1) {
            this.setData({
              year: this.data.year - 1,
              month: 12
            });
          } else {
            this.setData({
              month: this.data.month - 1
            })
          }
          this.setData({
            days_array: this._setCalendarData(this.data.year, this.data.month)
          });
          eventDetail['currentYear'] = this.data.year;
          eventDetail['currentMonth'] = this.data.month;
          this.triggerEvent('prevMonth', eventDetail);
        },
    
        /**
         * 日期选择器变化
         */
        dateChange: function(event) {
          const eventDetail = {
            prevYear: this.data.year,
            prevMonth: this.data.month
          };
          const value = event.detail.value;
          const date = new Date(value);
          const year = date.getFullYear();
          const month = date.getMonth() + 1;
          this.setData({
            year: year,
            month: month,
            days_array: this._setCalendarData(year, month)
          });
    
          eventDetail['currentYear'] = year;
          eventDetail['currentMonth'] = month;
          this.triggerEvent('dateChange', eventDetail);
        },
    
        /**
         * 点击具体日期
         */
        dayClick: function(event) {
          const click_day = event.currentTarget.dataset.day;
    
          // 判断选中日期是否在范围内
          if (click_day.year < this.data.min_year ||
            (click_day.year == this.data.min_year && click_day.month < this.data.min_month) ||
            (click_day.year == this.data.min_year && click_day.month == this.data.min_month && click_day.day < this.data.min_day)) {
            return;
          }
          if (click_day.year > this.data.max_year ||
            (click_day.year == this.data.max_year && click_day.month > this.data.max_month) ||
            (click_day.year == this.data.max_year && click_day.month == this.data.max_month && click_day.day > this.data.max_day)) {
            return;
          }
    
          // 选择单日期
          if (!this.data.moreDays) {
            this.triggerEvent('dayClick', click_day);
          } else {
            const click_day = event.currentTarget.dataset.day;
            if (dateStart == undefined) {
              dateStart = click_day;
              // 设置选中日期背景色
              let temp = temp = new Array(1);;
              
              temp[0] = {
                background: '#ea9518',
                day: dateStart.day,
                month: dateStart.month
              }
              this.setData({
                days_color: temp
              });
              this.setData({
                days_array: this._setCalendarData(dateStart.year, dateStart.month)
              });
            } else {
              dateEnd = click_day;
            }
            if (dateEnd != undefined) {
              // 选择同一天返回
              if (dateStart.year == dateEnd.year && dateStart.month == dateEnd.month &&
                dateStart.day == dateEnd.day) {
                return;
              }
              
              // 当开始日期超过结束日期时,开始日期和结束日期对换
              if (dateStart.year > dateEnd.year || 
                (dateStart.year == dateEnd.year && dateStart.month > dateEnd.month) ||
                (dateStart.year == dateEnd.year && dateStart.month == dateStart.month && dateStart.day > dateEnd.day)) {
                let temp = dateEnd;
                dateEnd = dateStart;
                dateStart = temp;
              }
    
              const eventDetail = {
                dateStart: dateStart,
                dateEnd: dateEnd
              }
    
              // 设置选中日期背景色
              // 设置选中日期背景色
              let temp = new Array();
              var start = this.parse(dateStart.year + '-' + dateStart.month + '-' + dateStart.day, 'y-m-d');
              var end = this.parse(dateEnd.year + '-' + dateEnd.month + '-' + dateEnd.day, 'y-m-d');
              for (let i = 0; start <= end && i < 20; i++) {
                temp.push({
                  day: start.getDate(),
                  month: start.getMonth() + 1,
                  background: "#ea9518"
                })
                start = this.nextDay(start);
              }
              this.setData({
                days_color: temp
              });
              console.log(this.data.days_color)
              this.setData({
                days_array: this._setCalendarData(click_day.year, click_day.month)
              });
    
              dateStart = undefined;
              dateEnd = undefined;
              // 睡眠3秒
              let start = new Date().getTime();
              while (true) if (new Date().getTime() - start > 1000) break;
    
              this.triggerEvent('dayClick', eventDetail);
            }
          }
        },
    
        /**
         * @description 将字符串转换为日期,支持格式y-m-d ymd (y m r)以及标准的
         * @return {Date} 返回日期对象
         */
        parse: function(dateStr, formatStr) {
          if (typeof dateStr === 'undefined') return null;
          if (typeof formatStr === 'string') {
            var _d = new Date(formatStr);
            //首先取得顺序相关字符串
            var arrStr = formatStr.replace(/[^ymd]/g, '').split('');
            if (!arrStr && arrStr.length != 3) return null;
    
            var formatStr = formatStr.replace(/y|m|d/g, function(k) {
              switch (k) {
                case 'y':
                  return '(\d{4})';
                case 'm':
                  ;
                case 'd':
                  return '(\d{1,2})';
              }
            });
    
            var reg = new RegExp(formatStr, 'g');
            var arr = reg.exec(dateStr)
    
            var dateObj = {};
            for (var i = 0, len = arrStr.length; i < len; i++) {
              dateObj[arrStr[i]] = arr[i + 1];
            }
            return new Date(dateObj['y'], dateObj['m'] - 1, dateObj['d']);
          }
          return null;
        },
    
        nextDay: function(d) {
          let end_date = new Date(d);
          end_date = +end_date + 1000*60*60*24;
          end_date = new Date(end_date);
          return end_date;
        },
      },
    
      created: function() {},
    
      attached: function() {
        const year = this.data.year;
        const month = this.data.month;
        this.setData({
          days_array: this._setCalendarData(year, month)
        });
      },
    
      ready: function() {},
    
      externalClasses: [
        'calendar-style', // 日历整体样式
        'header-style', // 标题样式
        'board-style', // 面板样式        
      ]
    })
    

      wxml

    <view class="calendar calendar-style">
        <!--主标题-->
        <view class="calendar-header header-style" wx:if="{{header}}">
            <text wx:if="{{year == min_year && month == min_month}}"></text>
            <text class="cwj-icon cwj-calendar-icon-left" bindtap="prevMonth" wx:elif="{{prev}}"></text>
            <text wx:else></text>
            
            <picker mode="date" value="{{year}}-{{month}}" start="{{startDate}}" end="{{endDate}}" bindchange="dateChange" fields="month">
                <text>{{year}}年{{month}}月</text>
            </picker>
            
            <text wx:if="{{year == max_year && month == max_month}}"></text>
            <text class="cwj-icon cwj-calendar-icon-right" bindtap="nextMonth" wx:elif="{{next}}"></text>
            <text wx:else></text>
        </view>
    
        <!--日历面板-->
        <view class="calendar-board board-style">
            <!--周标题-->
            <view class="calendar-weeks" wx:if="{{weeks && weekTitle.length == 7}}">
                <text class="calendar-weekday" wx:for="{{weekTitle}}" wx:key="unique">{{item}}</text>
            </view>
    
            <!--日期-->
            <view class="calendar-days">
                <block wx:for="{{days_array}}" wx:for-item="item" wx:key="unique" wx:for-index="i">
                    <!--日期行-->
                    <view class="calendar-row">
                        <block wx:for="{{days_array[i]}}" wx:for-item="day" wx:key="unique">
                            <view class="calendar-cell" style="background: {{day.background}};  {{cellSize}}px; height: {{cellSize}}px;" wx:if="{{day.day <= 0}}"></view>
                            <view class="calendar-cell" style="background: {{day.background}};  {{cellSize}}px; height: {{cellSize}}px;" wx:elif="{{activeType == 'square'}}" bindtap="dayClick" data-day="{{day}}">
                                <block wx:if="{{day.info == 'prev'}}">
                                    <text class="calendar-day" style="color: {{day.color}};">{{day.day}}</text>
                                    <block wx:if="{{addon == 'lunar'}}">
                                        <text class="calendar-lunar-day" style="color: {{day.color}};" wx:if="{{lunar}}">{{day.lunarDay}}</text>
                                    </block>
                                    <block wx:elif="{{addon == 'custom'}}">
                                        <text class="calendar-lunar-day" style="color: {{day.color}};">{{days_addon[c]}}</text>
                                    </block>
                                    <block wx:elif="{{addon == 'mixed'}}">
                                        <text class="calendar-lunar-day" style="color: {{day.color}};" wx:if="{{days_addon[i] != ''}}">{{days_addon[i]}}</text>
                                        <text class="calendar-lunar-day" style="color: {{day.color}};" wx:else>{{day.lunarDay}}</text>
                                    </block>
                                </block>
                                <block wx:elif="{{day.info == 'next'}}">
                                    <text class="calendar-day" style="color: {{day.color}};">{{day.day}}</text>
                                    <block wx:if="{{addon == 'lunar'}}">
                                        <text class="calendar-lunar-day" style="color: {{day.color}};" wx:if="{{lunar}}">{{day.lunarDay}}</text>
                                    </block>
                                    <block wx:elif="{{addon == 'custom'}}">
                                        <text class="calendar-lunar-day" style="color: {{day.color}};">{{days_addon[i]}}</text>
                                    </block>
                                    <block wx:elif="{{addon == 'mixed'}}">
                                        <text class="calendar-lunar-day" style="color: {{day.color}};" wx:if="{{days_addon[i] != ''}}">{{days_addon[i]}}</text>
                                        <text class="calendar-lunar-day" style="color: {{day.color}};" wx:else>{{day.lunarDay}}</text>
                                    </block>
                                </block>
                                <block wx:else>
                                    <text class="calendar-day" style="color: {{day.color}};">{{day.day}}</text>
                                    <block wx:if="{{addon == 'lunar'}}">
                                        <text class="calendar-lunar-day" style="color: {{day.color}};" wx:if="{{lunar}}">{{day.lunarDay}}</text>
                                    </block>
                                    <block wx:elif="{{addon == 'custom'}}">
                                        <text class="calendar-lunar-day" style="color: {{day.color}};">{{days_addon[i]}}</text>
                                    </block>
                                    <block wx:elif="{{addon == 'mixed'}}">
                                        <text class="calendar-lunar-day" style="color: {{day.color}};" wx:if="{{days_addon[i] != ''}}">{{days_addon[i]}}</text>
                                        <text class="calendar-lunar-day" style="color: {{day.color}};" wx:else>{{day.lunarDay}}</text>
                                    </block>                                
                                </block>                            
                            </view>
                            <view class="calendar-cell cell-rounded" style="background: {{day.background}};  {{cellSize}}px; height: {{cellSize}}px;" wx:else bindtap="dayClick" data-day="{{day}}">
                                <block wx:if="{{day.info == 'prev'}}">
                                    <text class="calendar-day" style="color: {{day.color}};">{{day.day}}</text>
                                    <block wx:if="{{addon == 'lunar'}}">
                                        <text class="calendar-lunar-day" style="color: {{day.color}};" wx:if="{{lunar}}">{{day.lunarDay}}</text>
                                    </block>
                                    <block wx:elif="{{addon == 'custom'}}">
                                        <text class="calendar-lunar-day" style="color: {{day.color}};">{{days_addon[i]}}</text>
                                    </block>
                                    <block wx:elif="{{addon == 'mixed'}}">
                                        <text class="calendar-lunar-day" style="color: {{day.color}};" wx:if="{{days_addon[i] != ''}}">{{days_addon[i]}}</text>
                                        <text class="calendar-lunar-day" style="color: {{day.color}};" wx:else>{{day.lunarDay}}</text>
                                    </block>
                                </block>
                                <block wx:elif="{{day.info == 'next'}}">
                                    <text class="calendar-day" style="color: {{day.color}};">{{day.day}}</text>
                                    <block wx:if="{{addon == 'lunar'}}">
                                        <text class="calendar-lunar-day" style="color: {{day.color}};" wx:if="{{lunar}}">{{day.lunarDay}}</text>
                                    </block>
                                    <block wx:elif="{{addon == 'custom'}}">
                                        <text class="calendar-lunar-day" style="color: {{day.color}};">{{days_addon[i]}}</text>
                                    </block>
                                    <block wx:elif="{{addon == 'mixed'}}">
                                        <text class="calendar-lunar-day" style="color: {{day.color}};" wx:if="{{days_addon[i] != ''}}">{{days_addon[i]}}</text>
                                        <text class="calendar-lunar-day" style="color: {{day.color}};" wx:else>{{day.lunarDay}}</text>
                                    </block>
                                </block>
                                <block wx:else>
                                    <text class="calendar-day" style="color: {{day.color}};">{{day.day}}</text>
                                    <block wx:if="{{addon == 'lunar'}}">
                                        <text class="calendar-lunar-day" style="color: {{day.color}};" wx:if="{{lunar}}">{{day.lunarDay}}</text>
                                    </block>
                                    <block wx:elif="{{addon == 'custom'}}">
                                        <text class="calendar-lunar-day" style="color: {{day.color}};">{{days_addon[i]}}</text>
                                    </block>
                                    <block wx:elif="{{addon == 'mixed'}}">
                                        <text class="calendar-lunar-day" style="color: {{day.color}};" wx:if="{{days_addon[i] != ''}}">{{days_addon[i]}}</text>
                                        <text class="calendar-lunar-day" style="color: {{day.color}};" wx:else>{{day.lunarDay}}</text>
                                    </block>                                
                                </block>                          
                            </view>
                        </block>
                    </view>
                </block>
            </view>
        </view>
    </view>
    

      wxss

    /* plugin/components/calendar/calendar.wxss */
    
    /*
     * 字体
     */
    
    
    @font-face {font-family: "cwj-icon";
      src: url('//at.alicdn.com/t/font_601455_q8aev4obbmon7b9.eot?t=1522928336476'); /* IE9*/
      src: url('//at.alicdn.com/t/font_601455_q8aev4obbmon7b9.eot?t=1522928336476#iefix') format('embedded-opentype'), /* IE6-IE8 */
      url('data:application/x-font-woff;charset=utf-8;base64,d09GRgABAAAAAAX4AAsAAAAACPAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADMAAABCsP6z7U9TLzIAAAE8AAAARAAAAFZW7kiWY21hcAAAAYAAAAB+AAABzpwV1GtnbHlmAAACAAAAAdkAAAJk5SF38GhlYWQAAAPcAAAALwAAADYQ95uWaGhlYQAABAwAAAAcAAAAJAfeA4hobXR4AAAEKAAAABMAAAAcG+kAAGxvY2EAAAQ8AAAAEAAAABACVgLCbWF4cAAABEwAAAAfAAAAIAEWAF1uYW1lAAAEbAAAAU8AAAJtar8thnBvc3QAAAW8AAAAOwAAAEyzyDbJeJxjYGRgYOBikGPQYWB0cfMJYeBgYGGAAJAMY05meiJQDMoDyrGAaQ4gZoOIAgCKIwNPAHicY2Bk/ss4gYGVgYOpk+kMAwNDP4RmfM1gxMjBwMDEwMrMgBUEpLmmMDgwVDxbztzwv4EhhrmBoQEozAiSAwAxYA0YeJzFkdENgzAMRJ8bQBHqKIzBEIzRr4pNmICymdeAc8xPJ+CsF9knR45ioAeKmEQH9sUIfeRa8wtj8ztm1SOVl2L16psf5ykv873lKVNfRuSD+ovua5YNPCZ7bvS/3u1c7ip+ZL3RE70m4fuW6P/wPYlt+S+JjfmR0F/MVB7gAAB4nG2Ru27UQBSG5x/jmd1k18b22F57s3d2BxSwhNfrFAinCC5AKZCQkCjpSdpQUERICAoKngEh5QFoU6fIvgMSAglaUnIZmFkCNIxGpzvf+b9ziE3Iz/fWsdUhAblMrpNb5C4hYJsYO7SHkSwyuolwZIexcCw5kSM+GWfWTcRjJqK8LGYx48yFgz7mo7yUGZVYFBW9gTzqAUk3vedPN3zrFdY6sv9M3aGvEQ4mG251Td2+ui3yYdA4aPl+4vsvG8y2G5RecB3sxVHTbq4x9cZ20/B4cIUO0EpkuvugPez6D18U+71p3AQODxF0h87Rtpd6+j9Jo8BP+MV2o5O2J5cEDj6ud4JWb/aB6AdT6Ak90a7aUcSIKswkMmyh0pXjkQix4F4LXC0ZGEqOlsdxFOSB+sLgeAyu7dhImOeA/WVauzRbMcs81ouoIFc0s6EtKNbWnasGdRbkQn1mhvODMXXKqMGXAqFa6rH8H+++4U1Nf5mBcb1gwzSZ34k80DwTRp1ptvqk2ez7f5P/cX577hwJvjqVphYSMwdRTJ/qIMvfnotQqFMDYXiuNbWySQ1X62tlM/Gc9xjfyLrm9RE74BlkBUrmO8DOvKiBGl9pPZ/XFHVR1L8AAj1YKgAAAHicY2BkYGAA4nnT6yri+W2+MnCzMIDAtTfaFxD0/4csDMwSQC4HAxNIFABKBgtfAHicY2BkYGBu+N/AEMPCAAJAkpEBFbADAEcNAnB4nGNhYGBgfsnAwMKAiQEWswEFAAAAAAAAdgCgAMgA8AEYATJ4nGNgZGBgYGcIZGBlAAEmIOYCQgaG/2A+AwARYwF0AHicZY9PTsJAGMVf+aeWxBCJ7kxmYVyolD9xxcYFCexZsIcyhTZtp5kOEA7geTyCJ/AIegPv4KNMXUCbmf7em/d98xXADX7g4Pjcch3ZwSXVkSu4wL3lKv0HyzXyi+U6mni13KD/ZtnFMyaWm2hDs4NTu6J6wrtlBy18WK7gGp+Wq/S/LNfI35bruMOv5QZaTtWyi5nTttzEoxO6Iy3nRi7FYi9CX6WBSo3r76LOQUzlahPPdSnL70zqPFSp6Hu90prIVOqyT75dDYwJRKBVIsZsKONYiUyrSPrGWxuTDbvdwPqerxKONeJvS8xhuC8hsMCeewgfCimCYjfM+dghQuf/ZMr8ChvErNVnp6d6xrRGTn1QAn146J2lJkylRfJ0nhxb3jagaziT4NKsSEhjO6HkJDFZICvOIjo+fQ/roirDEF2+wUneK+5O/gDGEWyYAHicY2BigAAuBuyAnZGJkZmRhZGVkY2RnZGDgbGCJSc1rYSptIAlJb88j7UoMz2jhDklv4SBAQB+nQh2AA==') format('woff'),
      url('//at.alicdn.com/t/font_601455_q8aev4obbmon7b9.ttf?t=1522928336476') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
      url('//at.alicdn.com/t/font_601455_q8aev4obbmon7b9.svg?t=1522928336476#cwj-icon') format('svg'); /* iOS 4.1- */
    }
    
    .cwj-icon {
      font-family:"cwj-icon" !important;
      font-size:16px;
      font-style:normal;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
    }
    
    .cwj-calendar-icon-left:before { content: "e697"; }
    
    .cwj-calendar-icon-up:before { content: "e6a5"; }
    
    .cwj-calendar-icon-down:before { content: "e6a6"; }
    
    .cwj-calendar-icon-right:before { content: "e6a7"; }
    
    .cwj-calendar-icon-dot:before { content: "e608"; }
    
    
    /**
     * 日历组件
     */
    
    .calendar {
        display: block;
        margin: 0rpx;
        font-size: 28rpx;
    }
    
    /**
     * 日历主标题
     */
    
    .calendar-header {
        display: flex;
        align-items: center;
        justify-content: space-around;    
        margin: 0rpx 20rpx 20rpx 20rpx;
        text-align: center;
        font-weight: bold;
    }
    
    /**
     * 日历周标题
     */
    
    .calendar-weeks {
        display: flex;
        justify-content: space-around;
        font-weight: bold;
    }
    
    /**
     * 日历周标题单个项目
     */
    
    .calendar-weekday {
        display: flex;
        justify-content: center;
        align-items: center;
         40rpx;
        height: 40rpx;
        margin-top: 10rpx;
        margin-bottom: 10rpx;    
        text-align: center;
    }
    
    /**
     * 日历日期行
     */
    
    .calendar-row {
        display: flex;
        justify-content: space-around;
    }
    
    /**
     * 日历单个日期项
     */
    
    .calendar-cell {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        margin-top: 10rpx;
        margin-bottom: 10rpx;    
        text-align: center;    
    }
    
    .cell-rounded {
        border-radius: 50%;
    }
    
    .calendar-lunar-day {    
        font-size: 20rpx;
    }
    

      lunar.js

    /* 
     * 农历数据表
     * 
     * 农历分大小月,大月30天,小月29天,但一年中哪个月为大月,哪个月为小月,是无规律的。
     * 农历每十年有4个闰年,但哪一年为闰年也是不确定的。
     * 而闰月中,哪个闰月为大月,哪个为小月也是不确定的。
     * 
     * 下面共20行,每行10个数据。每个数据代表一年,从阳历1900.1.31日起,为第一个数据年的开始,即阳历1900.1.31=农历0.1.1。
     * 200个数据可推200年的农历,因此目前最大只能推算到2100年
     * 
     * 对于每一个数据项,5个十六进制数 = 20个二进制位
     * 前4位,即0在这一年是闰年时才有意义,它代表这年闰月的大小月,为1则闰大月,为0则闰小月。
     * 中间12位,即4bd,每位代表一个月,为1则为大月,为0则为小月。
     * 最后4位,即8,代表这一年的闰月月份,为0则不闰。首4位要与末4位搭配使用。
     */
    const lunarInfo = new Array(
        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, 0x0a5d0, 0x14573, 0x052d0, 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, 0x0b5a0, 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年
    );
    
    const minYear = 1900; // 能计算的最小年份
    const maxYear = 2100; // 能计算的最大年份
    
    // 阳历每月天数,遇到闰年2月需加1天
    const solarMonth = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
    
    // 农历月份别称
    const monthName = new Array('正月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '冬月', '腊月');
    
    // 二十四节气
    const solarTerm = new Array(
        '小寒', '大寒', '立春', '雨水', '惊蛰', '春分',
        '清明', '谷雨', '立夏', '小满', '芒种', '夏至',
        '小暑', '大暑', '立秋', '处暑', '白露', '秋分',
        '寒露', '霜降', '立冬', '小雪', '大雪', '冬至'
    );
    
    // 二十节气相关系数
    const termInfo = new Array(
        0, 21208, 42467, 63836, 85337, 107014,
        128867, 150921, 173149, 195551, 218072, 240693,
        263343, 285989, 308563, 331033, 353350, 375494,
        397447, 419210, 440795, 462224, 483532, 504758);
    
    /**
     * 检查年份是否输入正确
     * @param year int 年份
     */
    function _checkYear(year) {
        if (year < minYear) {
            throw new RangeError('年份不能小于' + minYear + '年');
        } else if (year > maxYear) {
            throw new RangeError('年份不能大于' + maxYear + '年');
        }
        return true;
    }
    
    /**
     * 检查月份是否输入正确
     * @param month int 月份
     */
    function _checkMonth(month) {
        if (month < 1) {
            throw new RangeError('月份不能小于1');
        } else if (month > 12) {
            throw new RangeError('月份不能大于12');
        }
        return true;
    }
    
    /**
     * 检查日期是否输入正确
     * @param day int 日期
     */
    function _checkDay(day) {
        if (day < 1) {
            throw new RangeError('日期不能小于1');
        } else if (day > 31) {
            throw new RangeError('日期不能大于31');
        }
        return true;
    }
    
    /**
     * 返回农历year年中哪个月是闰月,没有闰月返回0
     * @param year int 年份
     */
    function getLunarLeapMonth(year) {
        if (_checkYear(year)) {
            return lunarInfo[year - minYear] & 0xf;  // 最后4位,代表这一年的闰月月份,为0则今年没有闰月
        }
    }
    
    /**
     * 返回农历year年闰月的天数(如果没有闰月则返回0)
     * @param year int 年份
     */
    function getLeapMonthDaysCount(year) {
        if (getLunarLeapMonth(year)) {
            return lunarInfo[year - minYear] & 0x10000 ? 30 : 29; // 前4位,即0在这一年是闰年时才有意义,它代表这年闰月的大小月
        }
        return 0;
    }
    
    /**
     * 返回农历year年的总天数
     * @param year int 年份
     */
    function getLunarYearDaysCount(year) {
        if (_checkYear(year)) {
            let sum = 348;  // 29天 * 12个月 = 348日    
            for (let i = 0x8000; i > 0x8; i >>= 1) {
                sum += (lunarInfo[year - minYear] & i ? 1 : 0);
            }
            return sum + getLeapMonthDaysCount(year);
        }
    }
    
    /**
     * 返回农历year年month月的天数
     * @param year int 年份
     * @param month int 月份 1~12
     */
    function getLunarYearMonthDaysCount(year, month) {
        if (_checkYear(year) && _checkMonth(month)) {
            return lunarInfo[year - minYear] & (0x10000 >> month) ? 30 : 29;
        }
    }
    
    /**
     * 农历日期的中文字符串
     * @param day int 日期
     */
    function getLunarDayString(day) {
        if (_checkDay(day)) {
            const nStr1 = new Array('日', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十');
            const nStr2 = new Array('初', '十', '廿', '卅');
            let str = '';
            switch (day) {
                case 10:
                    str = '初十';
                    break;
                case 20:
                    str = '二十';
                    break;
                case 30:
                    str = '三十';
                    break;
                default:
                    str = nStr2[Math.floor(day / 10)];
                    str += nStr1[day % 10];
                    break;
            }
            return str;
        }
    }
    
    /**
     * 返回某年的第n个节气为几日(从0小寒起算)
     * @param year int 年份
     * @param n 节气编号 0~23
     */
    function getLunarTermDay(year, n) {
        if (_checkYear(year) && n <= 23 && n >= 0) {
            const sTermInfo = new Array(0, 21208, 42467, 63836, 85337, 107014, 128867, 150921, 173149, 195551, 218072, 240693, 263343, 285989, 308563, 331033, 353350, 375494, 397447, 419210, 440795, 462224, 483532, 504758);
            const offDate = new Date((31556925974.7 * (year - minYear) + sTermInfo[n] * 60000) + Date.UTC(minYear, 0, 6, 2, 5));
            return offDate.getUTCDate();
        }
    }
    
    /**
     * 阳历日期转农历日期
     * @param year int 年份
     * @param month int 月份 1~12
     * @param day int 日期 1~31
     */
    function solarToLunar(year, month, day) {
        if (_checkYear(year) && _checkMonth(month) && _checkDay(day)) {
            const baseDate = new Date(minYear, 0, 31);      // 基础日期1900年1月31日
            const objDate = new Date(year, month - 1, day); // 目标日期
            let offset = (objDate - baseDate) / 86400000;   // 偏移天数 60 * 60 * 24 * 1000 = 86400000,1天的毫秒数
            let monCycle = 14;
            let temp = 0;
            let i = 0;
    
            for (i = minYear; i < maxYear && offset > 0; i++) {
                temp = getLunarYearDaysCount(i);             // 农历year年的总天数
                if (offset - temp < 0) {
                    break;
                } else {
                    offset -= temp;
                }
                monCycle += 12;
            }
    
    
            const lunarYear = i;                             // 农历年份        
            const leap = getLunarLeapMonth(lunarYear);       // 当年闰月是哪个月
            const isLeapYear = leap > 0 ? true : false;      // 当年是否有闰月        
            let isLeapMonth = false;                         // 当前农历月份是否是闰月
            for (i = 1; i <= 12 && offset > 0; i++) {
                if (leap > 0 && i == (leap + 1) && !isLeapMonth) {
                    --i;
                    isLeapMonth = true;
                    temp = getLeapMonthDaysCount(year);
                } else {
                    temp = getLunarYearMonthDaysCount(year, i);
                }
    
                if (isLeapMonth && i == (leap + 1)) {
                    isLeapMonth = false;
                }
    
                offset -= temp;
                if (!isLeapMonth) {
                    monCycle++;
                }
            }
    
            if (offset == 0 && leap > 0 && i == leap + 1) {
                if (isLeapMonth) {
                    isLeapMonth = false;
                } else {
                    isLeapMonth = true;
                    --i;
                    --monCycle;
                }
            }
    
            if (offset < 0) {
                offset += temp;
                --i;
                --monCycle;
            }
            const lunarMonth = i;        // 农历月份
            const lunarDay = offset + 1; // 农历日期
    
            let monthStr = '';
            if (isLeapYear) {
                if (lunarMonth < leap) {
                    monthStr = monthName[lunarMonth - 1];
                } else if (lunarMonth == leap) {
                    monthStr = '闰' + monthName[lunarMonth - 1];
                } else {
                    monthStr = monthName[lunarMonth - 2];
                }
            } else {
                monthStr = monthName[lunarMonth - 1];
            }
    
            return {
                year: lunarYear,                    // 农历年份
                month: lunarMonth,                  // 农历月份
                day: lunarDay,                      // 农历日期
                isLeap: isLeapMonth,                // 是否闰月
                monthStr: monthStr,                 // 月份字符串
                dayStr: getLunarDayString(lunarDay) // 日期字符串
            };
        }
    }
    
    /**
     * 阳历某个月份天数
     * @param year int 年份
     * @param month int 月份 1~12
     */
    function getSolarMonthDaysCount(year, month) {
        if (_checkYear(year) && _checkMonth(month)) {
            if (month == 2) {
                return (((year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0)) ? 29 : 28);
            } else {
                return solarMonth[month - 1];
            }
        }
    }
    
    /**
     * 获取指定日期是阳历年中的第几天
     * @param year int 年份
     * @param month int 月份 1-12
     * @param day int 日期
     */
    function getSolarDayNumber(year, month, day) {
        if (_checkYear(year) && _checkMonth(month) && _checkDay(day)) {
            const date = new Date(year, month - 1, day);
            const d = date.getDate(); // 本月第几天
            const m = month - 1;
            let sum = d;
            for (let i = 0; i < m; i++) {
                sum += solarMonth[i];
            }
    
            if (m > 1 && (year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
                sum += 1;
            }
    
            return sum;
        }
    }
    
    /**
     * 计算指定日期是否属于24节气
     * @param year int 年份
     * @param month int 月份 1~12
     * @param day int 日期 1~31
     */
    function getLunar24Days(year, month, day) {
        if (_checkYear(year) && _checkMonth(month) && _checkDay(day)) {
            const baseDate = new Date(1900, 0, 6, 2, 5, 0);
            let str = false;
            for (let i = 1; i <= 24; i++) {
                const num = 525948.76 * (year - 1900) + termInfo[i];
                const timestamp = baseDate.getTime() + num * 60 * 1000;
                const newDate = new Date(timestamp);
                if (getSolarDayNumber(newDate.getFullYear(), newDate.getMonth() + 1, newDate.getDate()) ==
                    getSolarDayNumber(year, month, day)) {
                    str = solarTerm[i];
                    break;
                }
            }
            return str;
        }
    }
    
    module.exports = {
        getLunarLeapMonth,          // 返回农历year年中哪个月是闰月,没有闰月返回0
        getLeapMonthDaysCount,      // 返回农历year年闰月的天数(如果没有闰月则返回0)
        getLunarYearDaysCount,      // 返回农历year年的总天数
        getLunarYearMonthDaysCount, // 返回农历year年month月的天数
        getLunarDayString,          // 农历日期的中文字符串        
        getLunarTermDay,            // 返回某年的第n个节气为第几日    
        getSolarMonthDaysCount,     // 获取阳历某个月份有多少天
        getSolarDayNumber,          // 获取指定日期是阳历年中的第几天
        getLunar24Days,             // 计算指定日期是否属于24节气    
        solarToLunar,               // 阳历日期转农历日期
    }
    

     在  其他页面中使用

    <!-- 日历组件 -->
    // 包裹了一层模态框 组件可以自己实现 <modalView show="{{showModal}}" clickMaskClose="{{clickMaskClose}}"> <view class="calendar"> <view class="calendar-cancel" bindtap="cancelSelect">取消</view> <calendar cell-size="45" weeks-type="cn" active-type="square" binddayClick="handleSelectDate" moreDays="true" show-more-days="true" startDate="{{startDate}}" endDate="{{endDate}}" /> </view> </modalView>

      

    // 包裹了一层模态框 
    js
    Component({
      /**
       * 组件的属性列表
       */
      properties: {
        //是否显示modal弹窗
        show: {
          type: Boolean,
          value: false,
          observer: '_setShow'
        },
        //控制底部是一个按钮还是两个按钮,默认两个
        single: {
          type: Boolean,
          value: false
        },
        // 控制clickMask是否关闭
        clickMaskClose: {
          type: Boolean,
          value: true,
          observer: '_setClickMaskClose'
        },
        top: {
          type: Number,
          value: 0
        },
        bottom: {
          type: Number,
          value: 0
        }
      },
    
      /**
       * 组件的初始数据
       */
      data: {
        clickMaskClose: true,
        show: false,
        top: 0,
        bottom: 0
      },
    
      /**
       * 组件的方法列表
       */
      methods: {
        _setClickMaskClose: function(newData, oldData) {
          this.setData({
            clickMaskClose: newData
          })
        },
        _setShow: function (newData, oldData) {
          this.setData({
            show: newData
          })
        },
        // 点击modal的回调函数
        clickMask: function() {
          // 点击modal背景关闭遮罩层,如果不需要注释掉即可
          if (this.data.clickMaskClose) {
            this.setData({ show: false })
          }
        },
        // 点击取消按钮的回调函数
        cancel: function() {
          this.setData({ show: false })
          this.triggerEvent('cancel')  //triggerEvent触发事件
        },
        // 点击确定按钮的回调函数
        confirm: function() {
          this.setData({ show: false })
          this.triggerEvent('confirm')
        }
      }
    })
    

      wxml

    <!--components/modal/modal.wxml-->
    <view class='modal-mask' wx:if='{{show}}' bindtap='clickMask'>
      <view class='modal-content' style="bottom: {{bottom}}px;">
        <scroll-view scroll-y class='main-content'>
          <slot></slot>
        </scroll-view>
      </view>
    </view>
    

      wxss

    /* components/modal/modal.wxss */
    /* components/modal/modal.wxss */
    /*遮罩层*/
    .modal-mask{
      display: flex;
      position: fixed;
      left: 0;
      right: 0;
      top: 0;
      bottom: 0;
      background-color: rgba(0,0,0,0.5);
      z-index: 9999999;
    }
    /*遮罩内容*/
    .modal-content{
      display: flex;
      position: absolute;
      flex-direction: column;
       100%;
      background-color: #fff;
    }
    /*中间内容*/
    .main-content{
      flex: 1;
      height: 100%;
      overflow-y: hidden; 
      max-height: 80vh; /* 内容高度最高80vh 以免内容太多溢出*/
    }
    

      

    苦心人,天不负
  • 相关阅读:
    UVA 10462 Is There A Second Way Left?(次小生成树&Prim&Kruskal)题解
    POJ 1679 The Unique MST (次小生成树)题解
    POJ 2373 Dividing the Path (单调队列优化DP)题解
    BZOJ 2709 迷宫花园
    BZOJ 1270 雷涛的小猫
    BZOJ 2834 回家的路
    BZOJ 2506 calc
    BZOJ 3124 直径
    BZOJ 4416 阶乘字符串
    BZOJ 3930 选数
  • 原文地址:https://www.cnblogs.com/taxun/p/13570522.html
Copyright © 2011-2022 走看看