| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525 |
- class Calendar {
- constructor({
- selected,
- startDate,
- endDate,
- range,
- isMonday
- } = {}) {
- // 当前日期
- this.date = this.getDateObj(new Date()) // 当前初入日期
- // 打点信息
- this.selected = selected || [];
- // 起始时间
- this.startDate = startDate
- // 终止时间
- this.endDate = endDate
- // 是否范围选择
- this.range = range
- // 是否周一开始
- this.isMonday = isMonday
- // 多选状态
- this.cleanMultipleStatus()
- // 每周日期
- this.weeks = {}
- this.lastHover = false
- }
- /**
- * 设置日期
- * @param {Object} date
- */
- setDate(date) {
- const selectDate = this.getDateObj(date)
- this.getWeeks(selectDate.fullDate)
- }
- /**
- * 清理多选状态
- */
- cleanMultipleStatus() {
- this.multipleStatus = {
- before: '',
- after: '',
- data: []
- }
- }
- setStartDate(startDate) {
- this.startDate = startDate
- }
- setEndDate(endDate) {
- this.endDate = endDate
- }
- getPreMonthObj(date) {
- date = fixIosDateFormat(date)
- date = new Date(date)
- const oldMonth = date.getMonth()
- date.setMonth(oldMonth - 1)
- const newMonth = date.getMonth()
- if (oldMonth !== 0 && newMonth - oldMonth === 0) {
- date.setMonth(newMonth - 1)
- }
- return this.getDateObj(date)
- }
- getNextMonthObj(date) {
- date = fixIosDateFormat(date)
- date = new Date(date)
- const oldMonth = date.getMonth()
- date.setMonth(oldMonth + 1)
- const newMonth = date.getMonth()
- if (newMonth - oldMonth > 1) {
- date.setMonth(newMonth - 1)
- }
- return this.getDateObj(date)
- }
- /**
- * 获取指定格式Date对象
- */
- getDateObj(date) {
- date = fixIosDateFormat(date)
- date = new Date(date)
- return {
- fullDate: getDate(date),
- year: date.getFullYear(),
- month: addZero(date.getMonth() + 1),
- date: addZero(date.getDate()),
- day: date.getDay()
- }
- }
- /**
- * 获取上一个月日期集合
- */
- getPreMonthDays(amount, dateObj) {
- const result = []
- for (let i = amount - 1; i >= 0; i--) {
- const month = dateObj.month - 1
- result.push({
- date: new Date(dateObj.year, month, -i).getDate(),
- month,
- disable: true
- })
- }
- return result
- }
- /**
- * 获取本月日期集合
- */
- getCurrentMonthDays(amount, dateObj) {
- const result = []
- const fullDate = this.date.fullDate
- for (let i = 1; i <= amount; i++) {
- const currentDate = `${dateObj.year}-${dateObj.month}-${addZero(i)}`
- const isToday = fullDate === currentDate
- // 获取打点信息
- const info = this.selected && this.selected.find((item) => {
- if (this.dateEqual(currentDate, item.date)) {
- return item
- }
- })
- // 日期禁用
- let disableBefore = true
- let disableAfter = true
- if (this.startDate) {
- disableBefore = dateCompare(this.startDate, currentDate)
- }
- if (this.endDate) {
- disableAfter = dateCompare(currentDate, this.endDate)
- }
- let multiples = this.multipleStatus.data
- let multiplesStatus = -1
- if (this.range && multiples) {
- multiplesStatus = multiples.findIndex((item) => {
- return this.dateEqual(item, currentDate)
- })
- }
- const checked = multiplesStatus !== -1
- result.push({
- fullDate: currentDate,
- year: dateObj.year,
- date: i,
- multiple: this.range ? checked : false,
- beforeMultiple: this.isLogicBefore(currentDate, this.multipleStatus.before, this
- .multipleStatus.after),
- afterMultiple: this.isLogicAfter(currentDate, this.multipleStatus.before, this
- .multipleStatus.after),
- month: dateObj.month,
- disable: (this.startDate && !dateCompare(this.startDate, currentDate)) || (this.endDate && !
- dateCompare(currentDate, this.endDate)),
- isToday,
- userChecked: false,
- extraInfo: info
- })
- }
- return result
- }
- /**
- * 获取下一个月日期集合
- */
- _getNextMonthDays(amount, dateObj) {
- const result = []
- const month = dateObj.month + 1
- for (let i = 1; i <= amount; i++) {
- result.push({
- date: i,
- month,
- disable: true
- })
- }
- return result
- }
- /**
- * 获取当前日期详情
- * @param {Object} date
- */
- getInfo(date) {
- if (!date) {
- date = new Date()
- }
- return this.calendar.find(item => item.fullDate === this.getDateObj(date).fullDate)
- }
- /**
- * 比较时间是否相等
- */
- dateEqual(before, after) {
- before = new Date(fixIosDateFormat(before))
- after = new Date(fixIosDateFormat(after))
- return before.valueOf() === after.valueOf()
- }
- /**
- * 比较真实起始日期
- */
- isLogicBefore(currentDate, before, after) {
- let logicBefore = before
- if (before && after) {
- logicBefore = dateCompare(before, after) ? before : after
- }
- return this.dateEqual(logicBefore, currentDate)
- }
- isLogicAfter(currentDate, before, after) {
- let logicAfter = after
- if (before && after) {
- logicAfter = dateCompare(before, after) ? after : before
- }
- return this.dateEqual(logicAfter, currentDate)
- }
- /**
- * 获取日期范围内所有日期
- * @param {Object} begin
- * @param {Object} end
- */
- geDateAll(begin, end) {
- var arr = []
- var ab = begin.split('-')
- var ae = end.split('-')
- var db = new Date()
- db.setFullYear(ab[0], ab[1] - 1, ab[2])
- var de = new Date()
- de.setFullYear(ae[0], ae[1] - 1, ae[2])
- var unixDb = db.getTime() - 24 * 60 * 60 * 1000
- var unixDe = de.getTime() - 24 * 60 * 60 * 1000
- for (var k = unixDb; k <= unixDe;) {
- k = k + 24 * 60 * 60 * 1000
- arr.push(this.getDateObj(new Date(parseInt(k))).fullDate)
- }
- return arr
- }
- /**
- * 获取多选状态
- */
- setMultiple(fullDate) {
- if (!this.range) return
- let {
- before,
- after
- } = this.multipleStatus
- if (before && after) {
- if (!this.lastHover) {
- this.lastHover = true
- return
- }
- this.multipleStatus.before = fullDate
- this.multipleStatus.after = ''
- this.multipleStatus.data = []
- this.multipleStatus.fulldate = ''
- this.lastHover = false
- } else {
- if (!before) {
- this.multipleStatus.before = fullDate
- this.lastHover = false
- } else {
- this.multipleStatus.after = fullDate
- if (dateCompare(this.multipleStatus.before, this.multipleStatus.after)) {
- this.multipleStatus.data = this.geDateAll(this.multipleStatus.before, this.multipleStatus
- .after);
- } else {
- this.multipleStatus.data = this.geDateAll(this.multipleStatus.after, this.multipleStatus
- .before);
- }
- this.lastHover = true
- }
- }
- this.getWeeks(fullDate)
- }
- /**
- * 鼠标 hover 更新多选状态
- */
- setHoverMultiple(fullDate) {
- if (!this.range || this.lastHover) return
- const {
- before
- } = this.multipleStatus
- if (!before) {
- this.multipleStatus.before = fullDate
- } else {
- this.multipleStatus.after = fullDate
- if (dateCompare(this.multipleStatus.before, this.multipleStatus.after)) {
- this.multipleStatus.data = this.geDateAll(this.multipleStatus.before, this.multipleStatus.after);
- } else {
- this.multipleStatus.data = this.geDateAll(this.multipleStatus.after, this.multipleStatus.before);
- }
- }
- this.getWeeks(fullDate)
- }
- /**
- * 更新默认值多选状态
- */
- setDefaultMultiple(before, after) {
- this.multipleStatus.before = before
- this.multipleStatus.after = after
- if (before && after) {
- if (dateCompare(before, after)) {
- this.multipleStatus.data = this.geDateAll(before, after);
- this.getWeeks(after)
- } else {
- this.multipleStatus.data = this.geDateAll(after, before);
- this.getWeeks(before)
- }
- }
- }
- /**
- * 获取每周数据
- * @param {Object} dateData
- */
- getWeeks(dateData) {
- const {
- year,
- month,
- } = this.getDateObj(dateData)
- let num = 1
- if (this.isMonday) {
- num = 0
- }
- const preMonthDayAmount = new Date(year, month - 1, num).getDay()
- const preMonthDays = this.getPreMonthDays(preMonthDayAmount, this.getDateObj(dateData))
- const currentMonthDayAmount = new Date(year, month, 0).getDate()
- const currentMonthDays = this.getCurrentMonthDays(currentMonthDayAmount, this.getDateObj(dateData))
- const nextMonthDayAmount = 42 - preMonthDayAmount - currentMonthDayAmount
- const nextMonthDays = this._getNextMonthDays(nextMonthDayAmount, this.getDateObj(dateData))
- const calendarDays = [...preMonthDays, ...currentMonthDays, ...nextMonthDays]
- const weeks = new Array(6)
- for (let i = 0; i < calendarDays.length; i++) {
- const index = Math.floor(i / 7)
- if (!weeks[index]) {
- weeks[index] = new Array(7)
- }
- weeks[index][i % 7] = calendarDays[i]
- }
- this.calendar = calendarDays
- this.weeks = weeks
- }
- }
- function getDateTime(date, hideSecond) {
- return `${getDate(date)} ${getTime(date, hideSecond)}`
- }
- function getDate(date) {
- date = fixIosDateFormat(date)
- date = new Date(date)
- const year = date.getFullYear()
- const month = date.getMonth() + 1
- const day = date.getDate()
- return `${year}-${addZero(month)}-${addZero(day)}`
- }
- function getTime(date, hideSecond) {
- date = fixIosDateFormat(date)
- date = new Date(date)
- const hour = date.getHours()
- const minute = date.getMinutes()
- const second = date.getSeconds()
- return hideSecond ? `${addZero(hour)}:${addZero(minute)}` : `${addZero(hour)}:${addZero(minute)}:${addZero(second)}`
- }
- function addZero(num) {
- if (num < 10) {
- num = `0${num}`
- }
- return num
- }
- function getDefaultSecond(hideSecond) {
- return hideSecond ? '00:00' : '00:00:00'
- }
- function dateCompare(startDate, endDate) {
- startDate = new Date(fixIosDateFormat(startDate))
- endDate = new Date(fixIosDateFormat(endDate))
- return startDate <= endDate
- }
- function checkDate(date) {
- const dateReg = /((19|20)\d{2})(-|\/)\d{1,2}(-|\/)\d{1,2}/g
- return date.match(dateReg)
- }
- const dateTimeReg = /^\d{4}-(0?[1-9]|1[012])-(0?[1-9]|[12][0-9]|3[01])( [0-5]?[0-9]:[0-5]?[0-9]:[0-5]?[0-9])?$/
- function fixIosDateFormat(value) {
- if (typeof value === 'string' && dateTimeReg.test(value)) {
- value = value.replace(/-/g, '/')
- }
- return value
- }
- // 页面初始时获取当前是本年第几周
- function getYearWeek(a, b, c) {
- //a为年 b为月 c为日
- /*
- date1是当前日期
- date2是当年第一天
- d是当前日期是今年第多少天
- 用d + 当前年的第一天的周差距的和在除以7就是本年第几周
- */
- var date1 = new Date(a, parseInt(b) - 1, c),
- date2 = new Date(a, 0, 1),
- d = Math.round((date1.valueOf() - date2.valueOf()) / 86400000);
- return Math.ceil((d + (date2.getDay() + 1 - 1)) / 7);
- }
- // 第n年的第n周,获取开始和结束时间 (星期一为一周的开始)
- function week_date(weekstr) {
- let year = weekstr.split("-")[0];
- let week = weekstr.split("-")[1];
- const date = new Date(year, 0, 1);
- const dayOfWeek = date.getDay();
- const difference = 1 - dayOfWeek;
- const firstWeekStart = new Date(year, 0, 1 + difference + (week - 1) * 7);
- const firstWeekEnd = new Date(year, 0, 1 + difference + (week - 1) * 7 + 6);
- console.log([
- convertDateFormat(firstWeekStart.toLocaleDateString()),
- convertDateFormat(firstWeekEnd.toLocaleDateString())
- ]);
- function convertDateFormat(dateString) {
- const parts = dateString.split('/');
- const year = parts[0];
- const month = parseInt(parts[1], 10).toString().padStart(2, '0');
- const day = parseInt(parts[2], 10).toString().padStart(2, '0');
- return `${year}-${month}-${day}`;
- }
- return [
- convertDateFormat(firstWeekStart.toLocaleDateString()),
- convertDateFormat(firstWeekEnd.toLocaleDateString())
- ];
- // 此年1号是星期几
- // console.log('调用时传的',year,weekNo);
- let oneday = new Date(year + "-01-01").getDay(); //0-6
- // console.log(oneday);
- // 方便计算,当为星期天时为7
- if (oneday == 0) {
- oneday = 7;
- }
- let one_fistday;
- let one_lastday;
- // 如果1号刚好是星期一
- if (oneday == 1) {
- one_fistday = year + "-01-01";
- one_lastday = year + "-01-07";
- } else {
- let jj = 8 - oneday;
- one_fistday =
- year -
- 1 +
- "-12-" +
- (31 - oneday + 2 > 9 ? 31 - oneday + 2 : "0" + (31 - oneday + 2));
- one_lastday = year + "-01-" + (jj > 9 ? jj : "0" + jj);
- }
- let fistday;
- let lastday;
- // 如果刚好是第一周
- if (weekNo == 1) {
- // 在原文档进行了修改
- fistday = addDate(one_fistday, 7);
- lastday = addDate(one_lastday, 7);
- } else {
- // 在原文档进行了修改
- fistday = addDate(one_lastday, (weekNo - 1) * 7 + 1);
- lastday = addDate(one_lastday, weekNo * 7);
- }
- return [fistday, lastday];
- }
- //日期加减法 date参数为计算开始的日期,days为需要加的天数
- //格式:addDate('2017-1-11',20)
- function addDate(date, days) {
- var d = new Date(date);
- d.setDate(d.getDate() + days);
- var m = d.getMonth() + 1;
- return (
- d.getFullYear() +
- "-" +
- (m > 9 ? m : "0" + m) +
- "-" +
- (d.getDate() > 9 ? d.getDate() : "0" + d.getDate())
- );
- }
- export {
- Calendar,
- getDateTime,
- getDate,
- getTime,
- addZero,
- getDefaultSecond,
- dateCompare,
- checkDate,
- fixIosDateFormat,
- getYearWeek,
- week_date
- }
|