import { pad } from './other' const weekMap = [ { name: '周日', value: 'SUN' }, { name: '周一', value: 'MON' }, { name: '周二', value: 'TUE' }, { name: '周三', value: 'WED' }, { name: '周四', value: 'THU' }, { name: '周五', value: 'FRI' }, { name: '周六', value: 'SAT' }, ] let weekValueMap = {} weekMap.map((item, index) => { weekValueMap[item.value] = { index, data: item } }) // const weekValueMap = 'MON,'.split(',') /* yyyy-MM-dd HH:mm:ss yyyy-M-d H:m:s 2018-06-23 20:30:00 => 0 30 20 23 6 ? 2018 */ export function time2cron (timestamp) { const date = new Date(timestamp) const yyyy = date.getFullYear() const M = date.getMonth() + 1 const d = date.getDate() const h = date.getHours() const m = date.getMinutes() const s = date.getSeconds() return `${s} ${m} ${h} ${d} ${M} ? ${yyyy}` } /* * 针对绝对时间,转换为时间戳 * 0 30 20 23 6 ? 2018 => */ export function cron2time (cron: string = '') { const [s, m, h, d, M, _, yyyy] = cron.split(' ') const ISOTime = `${yyyy}-${pad(M)}-${pad(d)}T${pad(h)}:${pad(m)}:${pad(s)}+08:00` return +new Date(ISOTime) } /* `0 30 20 ? * MON,TUE,FRI` 2018-05-04 20:30:00 2018-05-07 20:30:00 2018-05-08 20:30:00 2018-05-11 20:30:00 2018-05-14 20:30:00 HmStr: 09:20 */ /** * HmStr: 00:21 * repeatOptions: { weel: [1, 2] } */ export function cronRepeat (HmStr: string, repeatOptions: { week: Number[] }, now?: number) { HmStr = HmStr || '' let week = repeatOptions.week || [] let [H, m] = HmStr.split(':') if (!HmStr) { H = m = '0' } if (!week.length) { // 单条 return timeOnce(HmStr, now) } let arr: string[] = [] for (let day of week) { arr.push(weekMap[day + ''].value) } return `0 ${+m} ${+H} ? * ${arr.join(',')}` } /** * 判断是否比当前时间大,如果比当前时间小,跳到明天 * 构建 ISOTime 进行对比 2018-05-03T12:34:45+00:00 * @param HmStr 02:11 * @param now 当前时间戳 */ export function timeOnce (HmStr: string, nowTime = Date.now()) { if (!HmStr) { return '0 0 0 1 1 ? 2000' // 没有返回一个过去绝对时间 } const now: Date = new Date(nowTime) const yyyy = now.getFullYear() const M = now.getMonth() + 1 const d = now.getDate() let [h, m] = HmStr.split(':') const ISOTime = `${yyyy}-${pad(M)}-${pad(d)}T${pad(h)}:${pad(m)}:00+08:00` let targetTime = +new Date(ISOTime) const isTomorrow = +now > targetTime if (isTomorrow) targetTime += 86400000 return time2cron(targetTime) } /** * 解析 cron * `0 30 20 23 6 ? 2018` 绝对 * `0 30 20 ? * MON,TUE,FRI` 相对 */ let cache = {} export function cronParse (cron: string) { if (!cron) { return { week: [], str: '永不', isRepeat: false, isPast: false, hm: '', options: { week: [] } } } if (cache[cron]) { // console.warn(JSON.stringify(cache[cron], null, 2)) return cache[cron] } const [m, H] = cron.split(' ').slice(1) let isRepeat = false let isPast = false let str = '永不' let options = { week: [] as Number[] } if (cron.includes('? *')) isRepeat = true let weekArr: boolean[] = [] if (isRepeat) { let weekStr: string = cron.split('? * ')[1] let week: string[] = weekStr.split(',').filter(Boolean) options.week = week.map(item => weekValueMap[item].index) week.forEach(item => { weekArr[weekValueMap[item].index] = true }) str = '每' + week.map(item => weekValueMap[item].data.name).join(' ') if (weekStr === 'SUN,SAT') { str = '每个周末' } else if (weekStr === 'MON,TUE,WED,THU,FRI') { str = '每个工作日' } else if (weekStr === 'SUN,MON,TUE,WED,THU,FRI,SAT') { str = '每天' } } else { isPast = Date.now() > cron2time(cron) } cache[cron] = { week: weekArr, str, isRepeat, isPast, hm: `${pad(H)}:${pad(m)}`, options } // console.warn(JSON.stringify(cache[cron], null, 2)) return cache[cron] } // console.warn(JSON.stringify(cronParse('0 30 20 23 6 ? 2018'), null, 2)) // console.warn(JSON.stringify(cronParse('0 30 20 ? * MON,THU,FRI'), null, 2)) // console.warn(JSON.stringify(cronParse('0 30 20 ? * MON,THU,FRI'), null, 2)) // console.log(cronParse('0 30 20 23 6 ? 2018')) // alert(1)