/** * 格式化方法 * @param {Date|string|number} input - 输入时间,可以是Date对象、时间戳或ISO格式字符串 * @param {string} [format='YYYY-MM-DD hh:mm:ss'] - 格式化字符串 * @param {Object} [options] - 配置选项 * @param {string} [options.timeZone='local'] - 时区,'local'或'UTC' * @param {string} [options.locale='zh-CN'] - 区域设置 * @param {string} [options.defaultResult='-:-'] - 空值返回 * @returns {string} 格式化后的时间字符串 */ export function formatTime(input, format = 'YYYY-MM-DD hh:mm:ss', options = {}) { const { timeZone = 'local', locale = 'zh-CN', defaultResult = '-:-' } = options; try { // 1. 参数校验 if (input === null || input === undefined) { return defaultResult; } // 2. 转换为Date对象 let date; if (input instanceof Date) { date = new Date(input); } else if (typeof input === 'number') { date = new Date(input); } else if (typeof input === 'string') { // 尝试解析ISO格式或常见字符串格式 date = new Date(input); if (isNaN(date.getTime())) { // 尝试处理不带时区的格式 const cleanedInput = input.replace(/-/g, '/').replace(/T/, ' '); date = new Date(cleanedInput); if (isNaN(date.getTime())) { throw new Error(`Invalid date string: ${input}`); } } } else { return defaultResult; } // 检查日期是否有效 if (isNaN(date.getTime())) { return defaultResult; } // 3. 提取日期时间组件(根据时区选择方法) let year, month, day, hours, minutes, seconds, milliseconds, dayOfWeek; if (timeZone === 'UTC') { year = date.getUTCFullYear(); month = date.getUTCMonth() + 1; day = date.getUTCDate(); hours = date.getUTCHours(); minutes = date.getUTCMinutes(); seconds = date.getUTCSeconds(); milliseconds = date.getUTCMilliseconds(); dayOfWeek = date.getUTCDay(); } else { year = date.getFullYear(); month = date.getMonth() + 1; day = date.getDate(); hours = date.getHours(); minutes = date.getMinutes(); seconds = date.getSeconds(); milliseconds = date.getMilliseconds(); dayOfWeek = date.getDay(); } // 4. 定义替换规则 const replacements = { YYYY: String(year).padStart(4, '0'), YY: String(year).slice(-2), MM: String(month).padStart(2, '0'), M: String(month), DD: String(day).padStart(2, '0'), D: String(day), hh: String(hours).padStart(2, '0'), h: String(hours), HH: String(hours % 12 || 12).padStart(2, '0'), H: String(hours % 12 || 12), mm: String(minutes).padStart(2, '0'), m: String(minutes), ss: String(seconds).padStart(2, '0'), s: String(seconds), SSS: String(milliseconds).padStart(3, '0'), A: hours < 12 ? 'AM' : 'PM', a: hours < 12 ? 'am' : 'pm', ddd: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'][dayOfWeek], dddd: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][dayOfWeek], Q: Math.ceil((month) / 3), W: getWeekOfYear(date, timeZone), Z: timeZone === 'UTC' ? '+00:00' : formatTimeZoneOffset(date.getTimezoneOffset()) }; // 5. 执行替换 let result = format; for (const [token, value] of Object.entries(replacements)) { result = result.replace(new RegExp(token, 'g'), value); } // 6. 处理本地化月份和星期名称 if (result.includes('MMMM') || result.includes('MMM')) { const formatter = new Intl.DateTimeFormat(locale, { month: 'long', timeZone: timeZone === 'UTC' ? 'UTC' : undefined }); const longMonth = formatter.format(date); result = result.replace(/MMMM/g, longMonth); const shortFormatter = new Intl.DateTimeFormat(locale, { month: 'short', timeZone: timeZone === 'UTC' ? 'UTC' : undefined }); const shortMonth = shortFormatter.format(date); result = result.replace(/MMM/g, shortMonth); } if (result.includes('dddd') || result.includes('ddd')) { const formatter = new Intl.DateTimeFormat(locale, { weekday: 'long', timeZone: timeZone === 'UTC' ? 'UTC' : undefined }); const longDay = formatter.format(date); result = result.replace(/dddd/g, longDay); const shortFormatter = new Intl.DateTimeFormat(locale, { weekday: 'short', timeZone: timeZone === 'UTC' ? 'UTC' : undefined }); const shortDay = shortFormatter.format(date); result = result.replace(/ddd/g, shortDay); } return result; } catch (error) { console.error('Error formatting time:', error); return defaultResult; } } // 辅助函数:获取一年中的第几周 function getWeekOfYear(date, timeZone = 'local') { const tempDate = new Date(date); const firstDayOfYear = new Date(tempDate.getFullYear(), 0, 1); if (timeZone === 'UTC') { // 使用UTC方法计算 const utcDate = Date.UTC(tempDate.getUTCFullYear(), tempDate.getUTCMonth(), tempDate.getUTCDate()); const utcFirstDay = Date.UTC(firstDayOfYear.getUTCFullYear(), 0, 1); const pastDaysOfYear = (utcDate - utcFirstDay) / 86400000; return Math.ceil((pastDaysOfYear + firstDayOfYear.getUTCDay() + 1) / 7); } else { // 使用本地方法计算 const pastDaysOfYear = (tempDate - firstDayOfYear) / 86400000; return Math.ceil((pastDaysOfYear + firstDayOfYear.getDay() + 1) / 7); } } // 辅助函数:格式化时区偏移 function formatTimeZoneOffset(offset) { const sign = offset <= 0 ? '+' : '-'; const absOffset = Math.abs(offset); const hours = Math.floor(absOffset / 60); const minutes = absOffset % 60; return `${sign}${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}`; } /* // 基本格式 console.log(formatTime(now)); // "2023-05-15 14:30:45" console.log(formatTime(now, 'YYYY/MM/DD')); // "2023/05/15" console.log(formatTime(now, 'hh:mm:ss.SSS')); // "14:30:45.123" // 12小时制 console.log(formatTime(now, 'HH:mm:ss A')); // "02:30:45 PM" // 季度和周数 console.log(formatTime(now, 'YYYY-Q W')); // "2023-2 20" // 星期和月份名称 console.log(formatTime(now, 'dddd, MMMM D, YYYY')); // "Monday, May 15, 2023" // 不同区域设置 console.log(formatTime(now, 'dddd, MMMM D, YYYY', { locale: 'zh-CN' })); // "星期一, 五月 15, 2023" // UTC时间 console.log(formatTime(now, 'YYYY-MM-DD HH:mm:ss Z', { timeZone: 'UTC' })); // "2023-05-15 06:30:45 +00:00" // 不同输入类型 console.log(formatTime(1673789445123)); // 时间戳 console.log(formatTime('2023-01-15T14:30:45.123Z')); // ISO字符串 console.log(formatTime('2023/01/15 14:30:45')); // 普通字符串 */ export function isAfterTodayStart(timeString) { if (!timeString || typeof timeString !== 'string') { return false; } // 尝试多种日期格式解析 let inputDate; // 尝试标准格式 inputDate = new Date(timeString); // 如果解析失败,尝试其他常见格式 if (isNaN(inputDate.getTime())) { // 处理 YYYY-MM-DD 格式 if (/^\d{4}-\d{2}-\d{2}$/.test(timeString)) { inputDate = new Date(timeString + 'T00:00:00'); } // 处理 YYYY/MM/DD 格式 else if (/^\d{4}\/\d{2}\/\d{2}$/.test(timeString)) { inputDate = new Date(timeString.replace(/\//g, '-') + 'T00:00:00'); } // 处理时间戳 else if (/^\d+$/.test(timeString)) { inputDate = new Date(parseInt(timeString)); } } // 如果还是无效日期,返回false if (isNaN(inputDate.getTime())) { console.warn('无效的时间格式:', timeString); return false; } // 获取当前日期的零点时刻 const now = new Date(); const todayStart = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0, 0); return inputDate.getTime() > todayStart.getTime(); } /** * 格式化人名 * @param {string} name - 输入的人名 * @returns {string} 格式化后的人名 */ export function formatName(name) { // 1. 输入验证 if (name == null) return ''; // 处理null或undefined if (typeof name !== 'string') { // 尝试转换非字符串输入 try { name = String(name); } catch (e) { return ''; } } // 2. 去除首尾空白字符 name = name.trim(); // 3. 检查是否为空字符串 if (name.length === 0) return ''; // 4. 处理2个字符的情况(中文或英文) if (name.length === 2) { // 检查是否是有效字符(避免在符号或数字中间加空格) const isAllValidChars = /^[\p{L}\p{M}]{2}$/u.test(name); if (isAllValidChars) { return `${name[0]} ${name[1]}`; } } // 5. 返回其他情况的原名 return name; } // 计算时间范围 export function calculateTimeRange(activeTimeRange, timeRange) { const now = new Date(); let startDate = new Date(); let endDate = new Date(); switch (activeTimeRange) { case 'week': startDate.setDate(now.getDate() - 7); break; case 'month': // 本月:当前月份的第一天到当前天 startDate = new Date(now.getFullYear(), now.getMonth(), 1); endDate = new Date(now); break; case 'quarter': startDate.setDate(now.getDate() - 90); break; case 'year': // 本年:当前年份的第一天到当前天 startDate = new Date(now.getFullYear(), 0, 1); endDate = new Date(now); break; case 'custom': // 自定义时间范围:需要从组件中获取 // 假设组件有startDate和endDate属性 startDate = new Date(timeRange[0]); endDate = new Date(timeRange[1]); break; default: startDate.setDate(now.getDate() - 7); // 默认近一周 } // 格式化日期为YYYY-MM-DD格式 const formatDate = (date) => { const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, '0'); const day = String(date.getDate()).padStart(2, '0'); return `${year}-${month}-${day}`; }; return { startDate: formatDate(startDate), endDate: formatDate(endDate) } }