前端

关于日历相关业务-手写日历插件

2021-01-19  本文已影响0人  Raral

*前段时间公司有一个关于和日历有关的业务,需要通过用户不同选择日期做不同的数据统计分析,做报表用的,之前使用别人封装好的插件,但是不够灵活不能满足公司的需求,根据 一个时间段,可以连续不连续,根据周,根据月,根据年做一些数据统计分析,数据可视化插件是借助于G2展示数据---g2使用总结

//日历类
class Calendar  {
    constructor(options) {
        let opt = Object.assign({},this.defaultOptions, options)
        this.weektext = opt.weektext;
        this.weekstart = opt.weekstart;
        this.date = new Date();//获取当前的日期

        //模拟vue中的选中日期的状态(可以是连续的,也可以不连续的)
        //根据此数据做标记样式
        this.marksDate = [];// ["2021-01-01","2021-01-02",...]
        //根据数据渲染当月的日期
        this.dates = [];//当前月份对应的所有日期

    
    }
}
//默认配置
Calendar.prototype.defaultOptions = {
    
    weektext : ['日', '一', '二', '三', '四', '五', '六'],
    weekstart: 0,// 0 代表星期日
     /**
     * 根据需求补充配置
     */
}

// 业务method
// 日的操作 
//获取当天的日期信息
Calendar.prototype.getToday = function() {
    return this.dateInfo(new Date());
}
//获取昨天的日期信息
Calendar.prototype.getYesterday = function() {
    return this.changeDate(2, "prev", this.getToday()).slice(1)[0];
}
//获取明天的日期信息
Calendar.prototype.getTomorrowday = function() {
    return this.changeDate(2, "next",this.getToday()).slice(1)[0];
}
//获取用户选择的某一天
Calendar.prototype.getSelectday = function(selectDate) {
    return this.dateInfo(new Date(selectDate.time))
}

// 通过日历获取一个范围时间段(连续的)
Calendar.prototype.getStartAndEnd = function(startDate,endDate) {
    var diff = Math.abs(endDate.time - startDate.time);
    var days = parseInt(diff / (1000 * 60 * 60 * 24));
    return this.changeDate(days + 1, "next",startDate);
}
//通过日历用户点击多选择不同的日期数组
Calendar.prototype.addDatesArr = function(date) {
    this.marksDate.push(date);
    return  this.marksDate
}

//获取选择的日期所在的周(7天)
Calendar.prototype.getsevenDay = function(selectDate) {
    let weekIndex = selectDate.weekIndex;
    let prevDates = this.changeDate(weekIndex, "prev", selectDate);
    let nextDates = this.changeDate(7 - weekIndex, "next", selectDate)
    //数据处理
    prevDates.reverse();
    prevDates = prevDates.slice(0,prevDates.length - 1);
    return prevDates.concat(nextDates)
}
//获取上一周
Calendar.prototype.getPrevweek = function() {
    let prevWeek = this.changeDate(7,"prev", this.getToday());
    let selectDate = prevWeek[prevWeek.length - 1];
    return this.getsevenDay(selectDate);

}
//获取下一周
Calendar.prototype.getNextweek = function() {
    let prevWeek = this.changeDate(8,"next", this.getToday());
    let selectDate = prevWeek[prevWeek.length - 1];
    return this.getsevenDay(selectDate);
}


//获取当前月的所有日期
Calendar.prototype.getCurmonth = function() {
    let cur = this.getToday();
    this.dates = this.monthDay(cur.year,cur.month);
    return this.dates;
}
//获取上一个月所有的日期
Calendar.prototype.getPrevmonth = function(y,m) {
    // 处理边界条件
    if(m + 1 == 2) {
        m = 12;
        y = y -1;
    }
    this.dates = this.monthDay(y,m);
    return this.dates;
}
//获取上一个月所有的日期
Calendar.prototype.getNextmonth = function(y, m) {
    // 处理边界条件
    if(m + 1 == 13) {
        m = 1;
        y = y  + 1;
    }
    this.dates = this.monthDay(y,m);
    return this.dates;
}

//改变年月 对应的月份的天数
Calendar.prototype.changeYearMonth = function(y,m) {
    this.dates = this.monthDay(y,m);
}



//左开右闭
Calendar.prototype.changeDate = function(index,type,date2) {
    let arrDates = [];
        if(type === "prev") {
            for(let i = 0; i <= index; i ++ ) {
                let time = new Date(date2.date).getTime() - 24*60*60*1000 * i;
                let date = this.dateInfo(new Date(time));
                arrDates.push(date)
            }
    
        }else if(type === "next") {
            for(let j = 0; j < index; j ++ ) {
                let time = new Date(date2.date).getTime() + 24*60*60*1000 * j;
                let date = this.dateInfo(new Date(time));
                arrDates.push(date)
            }
        } 

    return arrDates;
}



//工具method
//格式化星期几  将索引 => 对应星期几
Calendar.prototype.formatWeek = function(week) {
    return "星期" + this.weektext[week];
}
//格式化数字    将 3 => 03
Calendar.prototype.formatNum = function(num) {
    return Number(num) < 10? `0${num}` : num
}
//格式化日历对应日期    
Calendar.prototype.formatDate = function (y,m,d) {
    return `${y}-${m}-${d}`
}

//封装日期信息主要给前端使用
Calendar.prototype.dateInfo = function (date) {
   let time = date.getTime(),//当前时间戳
        y = date.getFullYear(),//当前年
        m = date.getMonth(),// 当前月 注意国外从0 开始
        d = date.getDate(),//当前日
        week = date.getDay(),//当前周索引
        formatWeek = this.formatWeek(week);
    let dateInfo = {//日期信息
        year:y,
        month:m + 1,
        date: this.formatDate(y,this.formatNum(m + 1), this.formatNum(d)),
        week:formatWeek,
        weekIndex:week,
        time:time,

        /**
         * 根据需求补充信息
         */
    }

    return dateInfo
}

// 获取月份对应的日期
Calendar.prototype.monthDay2 = function(y,month) {
    let dates = [];
    let m = Number(month);
    //当月的第一天对应的星期几
    let firtDayOfMonth = new Date(y,m - 1, 1).getDay();
    //当月的最后一天对应几号,也就是下个月的第0天
    let lastDayOfMonth = new Date(y, m, 0).getDate();
    //上个月的最后一天对应几号
    let lastDayOfLastMonth = new Date(y, m - 2, 0).getDate();
    //初始化 每个月第一天是 星期日
    let weekStart = this.weekStart === 7? 0 : this.weekStart;
    console.log(m,firtDayOfMonth,lastDayOfMonth,lastDayOfLastMonth,weekStart)

    // 当月的第一周有几天是 上个月的
    let startDay = (() => {
        if(firtDayOfMonth == weekStart) { //刚刚星期日 对应的第一天
            return 0
        }else if(firtDayOfMonth > weekStart) {// 从星期日后几天 才是这个月的第一天
            return firtDayOfMonth - weekStart
        }else {// 
            return 7 -  (weekStart - firtDayOfMonth)
        }
    })()

    let endDay = 7 - ((startDay + lastDayOfLastMonth) % 7)
    // 属于上个月的日期
    for(let i = 1; i < startDay; i ++) {
        dates.push({
            date: this.formatNum(lastDayOfLastMonth - startDay + i),
            day: weekStart + i - 1 || 7,
            month: m - 1 >= 0? this.formatNum(m - 1) : 12,
            year: m - 1 >= 0? y : y -1
        })
    }


    // 当月的日期
    for(let j = 1; j <= lastDayOfMonth; j ++) {
        dates.push({
            date: this.formatNum(j),
            day: (j % 7) + firtDayOfMonth - 1 || 7,
            month: this.formatNum(m),
            year: y,
            isCurM: true // 是否当前月份
        })
    }

    // 属于下月的日期
    for(let k = 1; k <= endDay; k ++) {
        dates.push({
            date: this.formatNum(k),
            day: (lastDayOfLastMonth + startDay + weekStart + k - 1) % 7 || 7,
            month: m + 1 <= 11? this.formatNum(m + 1) : 0,
            year: m + 1 <= 11? y : y + 1
        })
    }

    return dates;
}
Calendar.prototype.monthDay = function(y, month) {
    let dates = [];
    let m = Number(month);
    let firstDayOfMonth = new Date(y, m - 1, 1).getDay(); // 当月第一天星期几
    let lastDateOfMonth = new Date(y, m, 0).getDate(); // 当月最后一天
    let lastDayOfLastMonth = new Date(y, m - 2, 0).getDate(); // 上一月的最后一天
    let weekstart = this.weekstart == 7? 0 : this.weekstart;
    let startDay = (() => {
        // 周初有几天是上个月的
        if (firstDayOfMonth == weekstart) {
            return 0;
        } else if (firstDayOfMonth > weekstart) {
            return firstDayOfMonth - weekstart;
        } else {
            return 7 - weekstart + firstDayOfMonth;
        }
    })();
    let endDay = 7 - ((startDay + lastDateOfMonth) % 7); // 结束还有几天是下个月的
    for (let i = 1; i <= startDay; i++) {
        dates.push({
            date: this.formatNum(lastDayOfLastMonth - startDay + i),
            day: weekstart + i - 1 || 7,
            month: m - 1 >= 0 ? this.formatNum(m - 1) : 12,
            year: m - 1 >= 0 ? y : y - 1
        });
    }
    for (let j = 1; j <= lastDateOfMonth; j++) {
        dates.push({
            date: this.formatNum(j),
            day: (j % 7) + firstDayOfMonth - 1 || 7,
            month: this.formatNum(m),
            year: y,
            isCurM: true //是否当前月份
        });
    }
    for (let k = 1; k <= endDay; k++) {
        dates.push({
            date: this.formatNum(k),
            day: (lastDateOfMonth + startDay + weekstart + k - 1) % 7 || 7,
            month: m + 1 <= 11 ? this.formatNum(m + 1) : 0,
            year: m + 1 <= 11 ? y : y + 1
        });
    }
    // console.log(dates);
    return dates;
}


//需要处理交互的参数格式-根据后台接口需求而定
Calendar.prototype.axiosParams = function(arr) {
    if(arr.length < 0) return;
    let axiosParams = {};
    axiosParams['start'] = arr[0];
    axiosParams['end'] = arr.length <= 1? arr[0] : arr[arr.length - 1];
    return axiosParams;
}



let calendar = new Calendar();
console.log("---------日-------")
let cur = calendar.getToday();//获取今天日期
let start = calendar.getYesterday();//获取昨天日期
let end =  calendar.getTomorrowday();//获取明天日期
let c = calendar.getSelectday(start);//获取选择的日期

console.log(end,start);
let b = calendar.getStartAndEnd(start,end);//获取两个日期间的日期数组
console.log(b);
let a = calendar.getsevenDay(start);//获取选择的日期所在的周
console.log(a)
console.log("---------周-------")
let d = calendar.getPrevweek();
console.log(d);
let e = calendar.getNextweek();
console.log(e);
console.log("---------月-------")
let datas1 = calendar.getCurmonth();
console.log(datas1)


上一篇 下一篇

猜你喜欢

热点阅读