193 lines
7.1 KiB
JavaScript
193 lines
7.1 KiB
JavaScript
export function humanizeCronInChinese(cron) {
|
|
const tokens = cron.trim().split(' ');
|
|
const cronStruct = {
|
|
time: {
|
|
minute: compileNode(tokens[0]),
|
|
hour: compileNode(tokens[1])
|
|
},
|
|
date: {
|
|
dayInMonth: compileNode(tokens[2]),
|
|
month: compileNode(tokens[3]),
|
|
dayInWeek: compileNode(tokens[4])
|
|
}
|
|
};
|
|
|
|
cronStruct.date = compileDatePart(cronStruct.date);
|
|
cronStruct.time = compileTimePart(cronStruct.time);
|
|
|
|
if (cronStruct.date.anyCount === 3 && cronStruct.time.text[0] === '每') {
|
|
// 避免 '每日每分钟' 出现
|
|
cronStruct.date.text = '';
|
|
}
|
|
|
|
return cronStruct.date.text + cronStruct.time.text;
|
|
}
|
|
|
|
function compileNode(raw) {
|
|
const compiled = { raw };
|
|
compiled.isAny = raw === '*';
|
|
compiled.hasStepping = raw.indexOf('/') >= 0;
|
|
compiled.hasList = raw.indexOf(',') >= 0;
|
|
compiled.hasRange = raw.indexOf('-') >= 0;
|
|
compiled.values = raw.split(',');
|
|
return compiled;
|
|
}
|
|
|
|
function compileDatePart(date) {
|
|
date.anyCount = date.month.isAny + date.dayInMonth.isAny + date.dayInWeek.isAny;
|
|
if (date.anyCount === 3) {
|
|
date.text = '每日';
|
|
} else if (date.anyCount === 2) {
|
|
if (date.month.isAny === false) {
|
|
// X 月每日
|
|
date.text = parseMonthToken(date.month.raw) + '每日';
|
|
} else if (date.dayInMonth.isAny === false) {
|
|
// 每月 X 日
|
|
date.text = '每月' + parseDayInMonthToken(date.dayInMonth.raw);
|
|
} else {
|
|
// 每周 X
|
|
date.text = '每' + parseDayInWeekToken(date.dayInWeek.raw);
|
|
}
|
|
} else if (date.anyCount === 1) {
|
|
if (date.month.isAny) {
|
|
// 每月 X 日或周 X
|
|
date.text = '每月' + parseDayInMonthToken(date.dayInMonth.raw) + '或' + parseDayInWeekToken(date.dayInWeek.raw);
|
|
} else if (date.dayInMonth.isAny) {
|
|
// X 月的每周 X
|
|
date.text = parseMonthToken(date.month.raw) + '的每' + parseDayInWeekToken(date.dayInWeek.raw);
|
|
} else {
|
|
// X 月 X 日
|
|
date.text = parseMonthToken(date.month.raw) + parseDayInMonthToken(date.dayInMonth.raw);
|
|
}
|
|
} else {
|
|
// X月X日或周X
|
|
date.text = parseMonthToken(date.month.raw) + parseDayInMonthToken(date.dayInMonth.raw) + '或' + parseDayInWeekToken(date.dayInWeek.raw);
|
|
}
|
|
|
|
return date;
|
|
}
|
|
|
|
function compileTimePart(time) {
|
|
time.anyCount = time.hour.isAny + time.minute.isAny;
|
|
if (time.anyCount === 2) {
|
|
time.text = '每分钟';
|
|
} else if (time.anyCount === 1) {
|
|
if (time.hour.isAny) {
|
|
if (time.minute.hasStepping) {
|
|
const parts = time.minute.raw.split('/');
|
|
if (time.minute.hasRange || time.minute.hasList) {
|
|
time.text = '每小时的第' + parts[0] + '分钟(间隔' + parts[1] + '分钟)';
|
|
} else {
|
|
time.text = '每隔' + time.minute.raw.split('/')[1] + '分钟';
|
|
}
|
|
} else {
|
|
time.text = '每小时的第' + time.minute.raw + '分钟';
|
|
}
|
|
} else {
|
|
if (time.hour.hasStepping) {
|
|
const parts = time.hour.raw.split('/');
|
|
if (time.hour.hasRange || time.hour.hasList) {
|
|
time.text = parts[0] + '时的每一分钟(间隔' + parts[1] + '小时)';
|
|
} else {
|
|
time.text = '每隔' + time.minute.raw.split('/')[1] + '分钟';
|
|
}
|
|
} else {
|
|
time.text = time.hour.raw + '时的每一分钟';
|
|
}
|
|
}
|
|
} else {
|
|
if (time.hour.hasStepping || time.minute.hasStepping) {
|
|
let hourString;
|
|
if (time.hour.hasStepping) {
|
|
const parts = time.hour.raw.split('/');
|
|
if (time.hour.hasList || time.hour.hasRange) {
|
|
hourString = parts[0] + '时(间隔' + parts[1] + '小时)';
|
|
} else {
|
|
hourString = '每' + parts[1] + '小时';
|
|
}
|
|
} else {
|
|
hourString = time.hour.raw + '时';
|
|
}
|
|
|
|
let minuteString;
|
|
if (time.minute.hasStepping) {
|
|
const parts = time.minute.raw.split('/');
|
|
if (time.minute.hasRange || time.minute.hasList) {
|
|
minuteString = '第' + parts[0] + '分钟(间隔' + parts[1] + '分钟)';
|
|
} else {
|
|
minuteString = '每' + parts[1] + '分钟';
|
|
}
|
|
} else {
|
|
minuteString = '第' + time.minute.raw + '分钟';
|
|
}
|
|
|
|
time.text = hourString + '的' + minuteString;
|
|
return time;
|
|
}
|
|
|
|
if (!time.hour.hasList && !time.hour.hasRange) {
|
|
if (!time.minute.hasList) {
|
|
if (time.minute.hasRange) {
|
|
// XX:XX - XX:YY
|
|
const minuteRange = time.minute.raw.split('-');
|
|
time.text = time.hour.raw.padStart(2, '0') + ':' + minuteRange[0].padStart(2, '0') + '-' + time.hour.raw.padStart(2, '0') + ':' + minuteRange[1].padStart(2, '0');
|
|
} else {
|
|
// XX:XX
|
|
time.text = time.hour.raw.padStart(2, '0') + ':' + time.minute.raw.padStart(2, '0');
|
|
}
|
|
} else {
|
|
time.text = time.hour.raw + '时的第' + time.minute.raw + '分钟';
|
|
}
|
|
} else {
|
|
time.text = time.hour.raw + '时的第' + time.minute.raw + '分钟';
|
|
}
|
|
}
|
|
|
|
return time;
|
|
}
|
|
|
|
function parseMonthToken(month) {
|
|
// replace month name if any
|
|
monthMap.forEach((x, i) => {
|
|
month = month.replace(x, (i + 1).toString());
|
|
});
|
|
if (month.indexOf('/') >= 0) {
|
|
const parts = month.split('/');
|
|
return parts[0] === '*' ? ('每' + parts[1] + '月') : (parts[0] + '月(间隔' + parts[1] + '月)');
|
|
}
|
|
|
|
return month + '月';
|
|
}
|
|
|
|
function parseDayInMonthToken(dayInMonth) {
|
|
if (dayInMonth.indexOf('/') >= 0) {
|
|
const parts = dayInMonth.split('/');
|
|
return parts[0] === '*' ? ('每' + parts[1] + '日') : (parts[1] + '日(间隔' + parts[1] + '日)');
|
|
}
|
|
return dayInMonth + '日';
|
|
}
|
|
|
|
function parseDayInWeekToken(dayInWeek) {
|
|
dayInWeekMap.forEach((x, i) => {
|
|
dayInWeek = dayInWeek.replace(x, i.toString());
|
|
});
|
|
if (dayInWeek.indexOf(',') >= 0) {
|
|
if (dayInWeek.indexOf('-') < 0) {
|
|
// 周三、四、六
|
|
return '周' + dayInWeek.split(',').map(x => dayInWeekNameMap[Number(x)]).join('、');
|
|
}
|
|
|
|
return dayInWeek.split(',').map(x => parseDayInWeekToken(x)).join(',');
|
|
}
|
|
|
|
if (dayInWeek.indexOf('-') >= 0) {
|
|
return dayInWeek.split('-').map(x => parseDayInWeekToken(x)).join('~');
|
|
}
|
|
|
|
return '周' + dayInWeekNameMap[Number(dayInWeek)];
|
|
}
|
|
|
|
const dayInWeekNameMap = ['日', '一', '二', '三', '四', '五', '六'];
|
|
const dayInWeekMap = ['SUN', 'MON', 'TUE', 'WEB', 'THU', 'FRI', 'SAT'].map(x => new RegExp(x, 'ig'));
|
|
const monthMap = ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC'].map(x => new RegExp(x, 'ig'));
|