function addYear(var1, years) {
if(!Number.isInteger(years)) return "错误,years必须为整数";
let dateComponent = parseDateComponents(var1)
if(dateComponent.msg) return "日期格式错误!";
if(!dateComponent.format.includes("yyyy")) return "错误,日期必须包含年份";
let date = new Date(dateComponent.year, dateComponent.month-1, dateComponent.day, dateComponent.hour, dateComponent.minute, dateComponent.second)
date.setFullYear(date.getFullYear() + years)
return recoverDateFormat(date, dateComponent.format);
}
function addMonth(var1,months) {
if(!Number.isInteger(months)) return "错误,months必须为整数";
let dateComponent = parseDateComponents(var1)
if(!dateComponent.format.includes("MM")) return "错误,日期必须包含月份";
let date = new Date(dateComponent.year, dateComponent.month-1, dateComponent.day, dateComponent.hour, dateComponent.minute, dateComponent.second)
date.setMonth(date.getMonth() + months)
return recoverDateFormat(date, dateComponent.format)
}
function addDay(var1,days) {
if(!Number.isInteger(days)) return "错误,days必须为整数";
let dateComponent = parseDateComponents(var1)
if(!dateComponent.format.includes("dd")) return "错误,日期中必须含有day数据";
let date = new Date(dateComponent.year, dateComponent.month-1, dateComponent.day, dateComponent.hour, dateComponent.minute, dateComponent.second)
date.setDate(date.getDate() + days)
return recoverDateFormat(date, dateComponent.format)
}
function addHour(var1,hours) {
if(isNaN(hours)) return "错误,hours必须为数字";
let dateComponent = parseDateComponents(var1)
if(!dateComponent.format.includes("HH")) return "错误,日期中必须含有时间";
let date = new Date(dateComponent.year, dateComponent.month-1, dateComponent.day, dateComponent.hour, dateComponent.minute, dateComponent.second)
date.setTime(date.getTime() + hours*60*60*1000)
return recoverDateFormat(date, dateComponent.format)
}
function addMinutes(var1,minutes) {
if(isNaN(minutes)) return "错误,minutes必须为数字";
let dateComponent = parseDateComponents(var1)
if(!dateComponent.format.includes("mm")) return "错误,日期中必须含有分钟数";
let date = new Date(dateComponent.year, dateComponent.month-1, dateComponent.day, dateComponent.hour, dateComponent.minute, dateComponent.second)
date.setTime(date.getTime() + minutes*60*1000)
return recoverDateFormat(date, dateComponent.format)
}
function addSeconds(var1,seconds) {
if(!Number.isInteger(seconds)) return "错误,seconds必须为整数";
let dateComponent = parseDateComponents(var1)
if(!dateComponent.format.includes("ss")) return "错误,日期中必须含有秒数";
let date = new Date(dateComponent.year, dateComponent.month-1, dateComponent.day, dateComponent.hour, dateComponent.minute, dateComponent.second)
date.setTime(date.getTime() + seconds*1000)
return recoverDateFormat(date, dateComponent.format)
}
function yearSpan(var1, var2) {
dateComponent1 = parseDateComponents(var1);
dateComponent2 = parseDateComponents(var2);
if(dateComponent1.msg|| dateComponent2.msg|| dateComponent1.format!=dateComponent2.format)
return "日期格式错误或不一致";
date1 = new Date(dateComponent1.year, dateComponent1.month-1, dateComponent1.day, dateComponent1.hour, dateComponent1.minute, dateComponent1.second)
date2 = new Date(dateComponent2.year, dateComponent2.month-1, dateComponent2.day, dateComponent2.hour, dateComponent2.minute, dateComponent2.second)
if(date1 > date2) { [date1, date2] = [date2, date1] }
yearDiff = date2.getFullYear() - date1.getFullYear();
temp = new Date(date1);
temp.setFullYear(date2.getFullYear());
return date2 < temp ? yearDiff-1 : yearDiff;
}
function monthSpan(var1, var2){
dateComponent1 = parseDateComponents(var1);
dateComponent2 = parseDateComponents(var2);
if(dateComponent1.msg|| dateComponent2.msg|| dateComponent1.format!=dateComponent2.format)
return "日期格式错误或不一致";
date1 = new Date(dateComponent1.year, dateComponent1.month-1, dateComponent1.day, dateComponent1.hour, dateComponent1.minute, dateComponent1.second)
date2 = new Date(dateComponent2.year, dateComponent2.month-1, dateComponent2.day, dateComponent2.hour, dateComponent2.minute, dateComponent2.second)
if(date1 > date2) { [date1, date2] = [date2, date1] }
let monthDiff = (date2.getFullYear() - date1.getFullYear()) * 12
+ (date2.getMonth() - date1.getMonth());
const tempDate = new Date(date1);
tempDate.setMonth(tempDate.getMonth() + monthDiff);
return date2 < tempDate ? --monthDiff : monthDiff;
}
function daySpan(var1, var2){
dateComponent1 = parseDateComponents(var1);
dateComponent2 = parseDateComponents(var2);
date1 = new Date(dateComponent1.year, dateComponent1.month-1, dateComponent1.day, dateComponent1.hour, dateComponent1.minute, dateComponent1.second)
date2 = new Date(dateComponent2.year, dateComponent2.month-1, dateComponent2.day, dateComponent2.hour, dateComponent2.minute, dateComponent2.second)
if(date1 > date2) { [date1, date2] = [date2, date1] }
return Math.floor((date2 - date1)/(1000*60*60*24));
}
function minuteSpan(var1, var2){
dateComponent1 = parseDateComponents(var1);
dateComponent2 = parseDateComponents(var2);
date1 = new Date(dateComponent1.year, dateComponent1.month-1, dateComponent1.day, dateComponent1.hour, dateComponent1.minute, dateComponent1.second)
date2 = new Date(dateComponent2.year, dateComponent2.month-1, dateComponent2.day, dateComponent2.hour, dateComponent2.minute, dateComponent2.second)
if(date1 > date2) { [date1, date2] = [date2, date1] }
return Math.floor((date2 - date1)/(1000*60));
}
function compareTime(var1, var2) {
if( isEmpty(var1) && isEmpty(var2) ) return 0;
if( isEmpty(var1) || isEmpty(var2) ) throw "比较日期大小时,某个日期为空";
const validFormat = ["yyyy-MM-dd HH:mm:ss","yyyy-MM-dd HH:mm","yyyy-MM-dd HH","yyyy-MM-dd","yyyy-MM","yyyy","HH:mm:ss","HH:mm"];
dateComponent1 = parseDateComponents(var1);
dateComponent2 = parseDateComponents(var2);
if(!validFormat.includes(dateComponent1.format) || !validFormat.includes(dateComponent2.format) || dateComponent1.format!=dateComponent2.format)
throw "日期格式错误或格式不一致";
date1 = new Date(dateComponent1.year, dateComponent1.month-1, dateComponent1.day, dateComponent1.hour, dateComponent1.minute, dateComponent1.second)
date2 = new Date(dateComponent2.year, dateComponent2.month-1, dateComponent2.day, dateComponent2.hour, dateComponent2.minute, dateComponent2.second)
if(date1 < date2) return 1;
if(date1 > date2) return -1;
return 0;
}
function textDateTime(dateStr1, dateStr2, format1, format2) {
const monthAbbr = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
function parseDate(str, format) {
const patterns = {
'yyyy': { regex: /^(\d{4})$/, parts: ['year'] },
'MM': { regex: /^(\d{2})$/, parts: ['month'] },
'MMM': { regex: /^([A-Za-z]{3})$/, parts: ['monthAbbr'] },
'dd': { regex: /^(\d{2})$/, parts: ['day'] },
'yyyy-MM-dd': { regex: /^(\d{4})-(\d{2})-(\d{2})$/, parts: ['year', 'month', 'day'] },
'MM-dd': { regex: /^(\d{2})-(\d{2})$/, parts: ['month', 'day'] },
'dd-MMM-yyyy': { regex: /^(\d{2})-([A-Za-z]{3})-(\d{4})$/, parts: ['day', 'monthAbbr', 'year'] },
'dd-MMM': { regex: /^(\d{2})-([A-Za-z]{3})$/, parts: ['day', 'monthAbbr'] },
'MMM-yyyy': { regex: /^([A-Za-z]{3})-(\d{4})$/, parts: ['monthAbbr', 'year'] },
'yyyy-MM': { regex: /^(\d{4})-(\d{2})$/, parts: ['year', 'month'] },
'yyyy-MM-dd HH:mm': { regex: /^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2})$/, parts: ['year', 'month', 'day', 'hour', 'minute'] },
'yyyy-MM-dd HH': { regex: /^(\d{4})-(\d{2})-(\d{2}) (\d{2})$/, parts: ['year', 'month', 'day', 'hour'] },
'HH': { regex: /^(\d{2})$/, parts: ['hour'] },
'mm': { regex: /^(\d{2})$/, parts: ['minute'] },
'ss': { regex: /^(\d{2})$/, parts: ['second'] },
'HH:mm': { regex: /^(\d{2}):(\d{2})$/, parts: ['hour', 'minute'] },
'HH:mm:ss': { regex: /^(\d{2}):(\d{2}):(\d{2})$/, parts: ['hour', 'minute', 'second'] },
'mm:ss': { regex: /^(\d{2}):(\d{2})$/, parts: ['minute', 'second'] },
'dd-MMM-yyyy HH:mm': { regex: /^(\d{2})-([A-Za-z]{3})-(\d{4}) (\d{2}):(\d{2})$/, parts: ['day', 'monthAbbr', 'year', 'hour', 'minute'] },
'dd-MMM-yyyy HH': { regex: /^(\d{2})-([A-Za-z]{3})-(\d{4}) (\d{2})$/, parts: ['day', 'monthAbbr', 'year', 'hour'] }
};
const { regex, parts } = patterns[format];
const match = str.match(regex);
if (!match) throw new Error('Invalid format');
const result = {};
parts.forEach((part, index) => {
const value = match[index + 1];
switch(part) {
case 'year':
result.year = parseInt(value);
break;
case 'month':
result.month = parseInt(value) - 1;
break;
case 'monthAbbr':
result.month = monthAbbr.findIndex(m => m === value);
if (result.month === -1) throw new Error('Invalid month');
break;
case 'day':
result.day = parseInt(value);
break;
case 'hour':
result.hour = parseInt(value);
break;
case 'minute':
result.minute = parseInt(value);
break;
case 'second':
result.second = parseInt(value);
break;
}
});
if (result.month !== undefined && (result.month < 0 || result.month > 11)) throw new Error('Invalid month');
if (result.day !== undefined && (result.day < 1 || result.day > 31)) throw new Error('Invalid day');
if (result.hour !== undefined && (result.hour < 0 || result.hour > 23)) throw new Error('Invalid hour');
if (result.minute !== undefined && (result.minute < 0 || result.minute > 59)) throw new Error('Invalid minute');
if (result.second !== undefined && (result.second < 0 || result.second > 59)) throw new Error('Invalid second');
return result;
}
const date1 = parseDate(dateStr1, format1);
const date2 = parseDate(dateStr2, format2);
const merged = { ...date1, ...date2 };
const finalDate = new Date(
merged.year,
merged.month,
merged.day || 1,
merged.hour || 0,
merged.minute || 0,
merged.second || 0
);
if (isNaN(finalDate)) throw new Error('Invalid combined date');
if (finalDate.getDate() !== (merged.day || 1)) throw new Error('Invalid day');
if (merged.year !== undefined && finalDate.getFullYear() !== merged.year) throw new Error('Invalid year');
if (merged.month !== undefined && finalDate.getMonth() !== merged.month) throw new Error('Invalid month');
return `${finalDate.getFullYear()}-${String(finalDate.getMonth() + 1).padStart(2, '0')}-${String(finalDate.getDate()).padStart(2, '0')} ` +
`${String(finalDate.getHours()).padStart(2, '0')}:${String(finalDate.getMinutes()).padStart(2, '0')}:${String(finalDate.getSeconds()).padStart(2, '0')}`;
}
function formatDate(var1, format) {
const formatOptions = {
"yyyy": { year: "numeric" },
"yyyy-MM": { year: "numeric", month: "2-digit" },
"yyyy-MM-dd": { year: "numeric", month: "2-digit", day: "2-digit" },
"dd-MMM-yyyy": { day: "2-digit", month: "short", year: "numeric" },
"yyyy-MM-dd HH": { year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", hour12: false },
"dd-MMM-yyyy HH": { day: "2-digit", month: "short", year: "numeric", hour: "2-digit", hour12: false },
"yyyy-MM-dd HH:mm": { year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", hour12: false },
"dd-MMM-yyyy HH:mm": { day: "2-digit", month: "short", year: "numeric", hour: "2-digit", minute: "2-digit", hour12: false },
"HH:mm": { hour: "2-digit", minute: "2-digit", hour12: false },
"HH:mm:ss": { hour: "2-digit", minute: "2-digit", second: "2-digit", hour12: false }
};
const isChinese = /[\u4e00-\u9fa5]/.test(format);
const locale = isChinese ? "zh-CN" : "en-US";
const options = formatOptions[format];
if (!options) {
console.error("Unsupported format: " + format);
return null;
}
return new Intl.DateTimeFormat(locale, options).format(date).replace(",", "");
}
function parseDateComponents(dateStr) {
let result = { format: null, year: null, month: null, day: null, hour: null, minute: null, second: null ,msg: null};
const patterns = [
{ regex: /^(\d{2})-(\d{2})-(\d{4})$/, format: "dd-MM-yyyy" },
{ regex: /^(\d{2})-(\d{2})-(\d{4}) (\d{2}):(\d{2})$/, format: "dd-MM-yyyy HH:mm" },
{ regex: /^(\d{2})-(\d{2})-(\d{4}) (\d{2}):(\d{2}):(\d{2})$/, format: "dd-MM-yyyy HH:mm:ss" },
{ regex: /^(\d{2})-(\d{4})$/, format: "MM-yyyy" },
{ regex: /^(\d{4})-(\d{2})-(\d{2})$/, format: "yyyy-MM-dd" },
{ regex: /^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2})$/, format: "yyyy-MM-dd HH:mm" },
{ regex: /^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})$/, format: "yyyy-MM-dd HH:mm:ss" },
{ regex: /^(\d{4})-(\d{2})$/, format: "yyyy-MM" },
{ regex: /^(\d{4})$/, format: "yyyy" },
{ regex: /^(\d{2}):(\d{2}):(\d{2})$/, format: "HH:mm:ss" },
{ regex: /^(\d{2}):(\d{2})$/, format: "HH:mm" },
{ regex: /^(\d{2})$/, format: "HH" }
];
for (let pattern of patterns) {
let match = dateStr.match(pattern.regex);
if (match) {
switch (pattern.format) {
case "dd-MM-yyyy":
result = {format: pattern.format, year: +match[3], month: +match[2], day: +match[1], hour: null, minute: null, second: null };
break;
case "dd-MM-yyyy HH:mm":
result = {format: pattern.format, year: +match[3], month: +match[2], day: +match[1], hour: +match[4], minute: +match[5], second: null };
break;
case "dd-MM-yyyy HH:mm:ss":
result = {format: pattern.format, year: +match[3], month: +match[2], day: +match[1], hour: +match[4], minute: +match[5], second: +match[6] };
break;
case "MM-yyyy":
result = {format: pattern.format, year: +match[2], month: +match[1], day: 1, hour: null, minute: null, second: null };
break;
case "yyyy-MM-dd":
result = {format: pattern.format, year: +match[1], month: +match[2], day: +match[3], hour: null, minute: null, second: null };
break;
case "yyyy-MM-dd HH:mm":
result = {format: pattern.format, year: +match[1], month: +match[2], day: +match[3], hour: +match[4], minute: +match[5], second: null };
break;
case "yyyy-MM-dd HH:mm:ss":
result = {format: pattern.format, year: +match[1], month: +match[2], day: +match[3], hour: +match[4], minute: +match[5], second: +match[6] };
break;
case "yyyy-MM":
result = {format: pattern.format, year: +match[1], month: +match[2], day: 1, hour: null, minute: null, second: null };
break;
case "yyyy":
result = {format: pattern.format, year: +match[1], month: 1, day: 1, hour: null, minute: null, second: null };
break;
case "HH:mm:ss":
result = {format: pattern.format, year: null, month: null, day: null, hour: +match[1], minute: +match[2], second: +match[3] };
break;
case "HH:mm":
result = {format: pattern.format, year: null, month: null, day: null, hour: +match[1], minute: +match[2], second: null };
break;
case "HH":
result = {format: pattern.format, year: null, month: null, day: null, hour: +match[1], minute: null, second: null };
break;
}
return result;
}
}
result.msg = "错误:无法识别的日期格式"
return result;
}
function recoverDateFormat(dateObj, format) {
let yyyy = dateObj.getFullYear();
let MM = String(dateObj.getMonth() + 1).padStart(2, "0");
let dd = String(dateObj.getDate()).padStart(2, "0");
let HH = String(dateObj.getHours()).padStart(2, "0");
let mm = String(dateObj.getMinutes()).padStart(2, "0");
let ss = String(dateObj.getSeconds()).padStart(2, "0");
switch (format) {
case "yyyy-MM-dd":
return `${yyyy}-${MM}-${dd}`;
case "yyyy-MM-dd HH:mm":
return `${yyyy}-${MM}-${dd} ${HH}:${mm}`;
case "yyyy-MM-dd HH:mm:ss":
return `${yyyy}-${MM}-${dd} ${HH}:${mm}:${ss}`;
case "yyyy-MM":
return `${yyyy}-${MM}`;
case "yyyy":
return `${yyyy}`;
case "HH:mm:ss":
return `${HH}:${mm}:${ss}`;
case "HH:mm":
return `${HH}:${mm}`;
case "HH":
return `${HH}`;
case "dd-MM-yyyy":
return `${dd}-${MM}-${yyyy}`;
case "dd-MM-yyyy HH:mm":
return `${dd}-${MM}-${yyyy} ${HH}:${mm}`;
case "dd-MM-yyyy HH:mm:ss":
return `${dd}-${MM}-${yyyy} ${HH}:${mm}:${ss}`;
case "MM-yyyy":
return `${MM}-${yyyy}`;
default:
return "错误:无法格式化";
}
}
function isEmpty(value) {
return (
value == null ||
(typeof value === "string" && value.trim() === "") ||
(Array.isArray(value) && value.length === 0) ||
(typeof value === "object" && value !== null && Object.keys(value).length === 0) ||
(typeof value === "number" && isNaN(value))
);
}
console.log(addYear('20-01-2024 20:30:21', 1));
console.log(addMonth('2024-01-31 00:00:00',2));
console.log(addDay('2024-02-20 00:00:00',11));
console.log(addDay('2024-02',11));
console.log(addHour('2024-02-01 20:40:00',5.5));
console.log(addHour('20:40:00',5.5));
console.log(addMinutes('20:40:00',5.5));
console.log(addMinutes('2024-02-29 23:40:00',20.5));
console.log(addSeconds('2024-02-29 23:40:00',20));
console.log(addYear('2024/02/29 23:40:00',1));
console.log(yearSpan('2024/02/29 23:40:00','2024-02-01 00:00:00'));
console.log(yearSpan('2024-02-28 01:00:00','2025-02-28 01:02:20'));
console.log(yearSpan('2025-02-28 01:02:20','2024-02-28 01:00:00'));
console.log(yearSpan('01:00:00','01:02:20'));
console.log(monthSpan('2024-02-29','2025-02-28'));
console.log(monthSpan('2025-02-28','2025-06-01'));
console.log(daySpan('2025-02-28','2025-06-01'));
console.log(daySpan('2025-02-28 20:00:00','2025-06-01 10:00:00'));
console.log(minuteSpan('2025-02-28 20:00:00','2025-02-28 10:01:01'));
console.log(compareTime('2025-02-28 20:00:00','2025-02-28 20:00:00'));
console.log(compareTime('2025-02-28 20:00:00','2025-02-28 10:01:01'));
console.log(compareTime('2025-02-28 24:00:00','2025-03-01 00:00:00'));
console.log(textDateTime("2020-04-10","00:00:30","yyyy-MM-dd","HH:mm:ss"));
console.log(textDateTime("00:00:00","10-Dec-2020","HH:mm:ss","dd-MMM-yyyy"));