/**
* 根據傳入的時間字符串按照格式轉換並返回
* @param { string } dateString 傳入的時間字符串
* @param { string } format 需要轉換的格式
* @param { object } options 配置項
* @returns { string } 轉換後的時間
*/
function formatDate(dateString, format = 'YYYY-MM-DD', options = {}) {
const {
invalidText = '', // 無效日期時的返回文本
strictMode = false // 嚴格模式,無效日期拋出錯誤
} = options;
try {
// 處理空值情況
if (!dateString) return invalidText;
const date = new Date(dateString);
// 檢查日期是否有效
if (isNaN(date.getTime())) {
if (strictMode) {
throw new Error('Invalid date string');
}
return invalidText;
}
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
const hours = date.getHours();
const minutes = date.getMinutes();
const seconds = date.getSeconds();
const milliseconds = date.getMilliseconds();
const dayOfWeek = date.getDay();
// 周幾的中英文映射
const weekdays = {
en: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
enShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
zh: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'],
zhShort: ['週日', '週一', '週二', '週三', '週四', '週五', '週六']
};
// 月份的中英文映射
const months = {
en: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
enShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
zh: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月']
};
// 定義格式映射
const formatMap = {
'YYYY': year,
'YY': String(year).slice(-2),
'MM': String(month).padStart(2, '0'),
'M': month,
'DD': String(day).padStart(2, '0'),
'D': day,
'HH': String(hours).padStart(2, '0'),
'H': hours,
'hh': String(hours % 12 || 12).padStart(2, '0'),
'h': hours % 12 || 12,
'mm': String(minutes).padStart(2, '0'),
'm': minutes,
'ss': String(seconds).padStart(2, '0'),
's': seconds,
'SSS': String(milliseconds).padStart(3, '0'),
'A': hours < 12 ? 'AM' : 'PM',
'a': hours < 12 ? 'am' : 'pm',
'dddd': weekdays.en[dayOfWeek],
'ddd': weekdays.enShort[dayOfWeek],
'星期': weekdays.zh[dayOfWeek],
'周': weekdays.zhShort[dayOfWeek],
'MMMM': months.en[month - 1],
'MMM': months.enShort[month - 1],
'Month': months.zh[month - 1]
};
// 按照格式長度從長到短排序
const formatKeys = Object.keys(formatMap).sort((a, b) => b.length - a.length);
let result = format;
// 逐個替換格式標記
formatKeys.forEach(key => {
const regex = new RegExp(key, 'g');
result = result.replace(regex, formatMap[key]);
});
return result;
} catch (error) {
console.error('日期格式化錯誤:', error);
return strictMode ? '' : invalidText;
}
}
測試效果
// 高級使用示例
console.log(formatDate("August 30, 2025", 'YYYY-MM-DD')); // "2025-08-30"
console.log(formatDate("August 30, 2025", 'YYYY年MM月DD日 周')); // "2025年08月30日 週六"
console.log(formatDate("August 30, 2025", 'MMMM DD, YYYY')); // "August 30, 2025"
console.log(formatDate("August 30, 2025", 'YYYY-MM-DD HH:mm:ss.SSS')); // "2025-08-30 00:00:00.000"
console.log(formatDate("invalid", 'YYYY-MM-DD', { invalidText: '無效日期' })); // "無效日期"
1.增加了 try-catch 和無效日期檢查
2.對 null、undefined、空字符串等情況進行處理
3.支持年月日時分秒、12/24小時制、AM/PM、周幾等
4.按標記長度排序,避免替換衝突
5.支持自定義無效日期返回文本和嚴格模式
6.支持中英文的月份和周幾顯示