| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321 |
- /**
- * 格式化方法
- * @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)
- }
- }
|