UNPKG

data-utils-grok

Version:

A comprehensive JavaScript utility library for data processing, organized by data types (arrays, objects, strings, forms, tables)

400 lines (351 loc) 10.4 kB
// src/dateUtils.js /** * 日期类型处理工具函数 */ /** * 格式化日期 * @param {Date|string|number} date - 日期对象、日期字符串或时间戳 * @param {string} [format='YYYY-MM-DD'] - 格式化模板 * @returns {string} 格式化后的日期字符串 */ function formatDate(date, format = 'YYYY-MM-DD') { if (!date) { throw new TypeError('Date is required'); } const d = new Date(date); if (isNaN(d.getTime())) { throw new TypeError('Invalid date'); } const year = d.getFullYear(); const month = String(d.getMonth() + 1).padStart(2, '0'); const day = String(d.getDate()).padStart(2, '0'); const hours = String(d.getHours()).padStart(2, '0'); const minutes = String(d.getMinutes()).padStart(2, '0'); const seconds = String(d.getSeconds()).padStart(2, '0'); const milliseconds = String(d.getMilliseconds()).padStart(3, '0'); return format .replace('YYYY', year) .replace('MM', month) .replace('DD', day) .replace('HH', hours) .replace('mm', minutes) .replace('ss', seconds) .replace('SSS', milliseconds); } /** * 解析日期字符串 * @param {string} dateString - 日期字符串 * @param {string} [format='YYYY-MM-DD'] - 日期格式 * @returns {Date} 解析后的日期对象 */ function parseDate(dateString, format = 'YYYY-MM-DD') { if (typeof dateString !== 'string') { throw new TypeError('Date string must be a string'); } // 支持多种常见格式 const patterns = { 'YYYY-MM-DD': /^(\d{4})-(\d{1,2})-(\d{1,2})$/, 'YYYY/MM/DD': /^(\d{4})\/(\d{1,2})\/(\d{1,2})$/, 'DD-MM-YYYY': /^(\d{1,2})-(\d{1,2})-(\d{4})$/, 'DD/MM/YYYY': /^(\d{1,2})\/(\d{1,2})\/(\d{4})$/, 'YYYY-MM-DD HH:mm:ss': /^(\d{4})-(\d{1,2})-(\d{1,2})\s+(\d{1,2}):(\d{1,2}):(\d{1,2})$/, }; const pattern = patterns[format]; if (!pattern) { throw new Error(`Unsupported format: ${format}`); } const match = dateString.match(pattern); if (!match) { throw new Error(`Date string does not match format: ${format}`); } let year, month, day, hours = 0, minutes = 0, seconds = 0; if (format.startsWith('YYYY')) { [, year, month, day, hours, minutes, seconds] = match; } else { [, day, month, year, hours, minutes, seconds] = match; } return new Date( parseInt(year), parseInt(month) - 1, parseInt(day), parseInt(hours) || 0, parseInt(minutes) || 0, parseInt(seconds) || 0 ); } /** * 获取日期差 * @param {Date|string|number} date1 - 第一个日期 * @param {Date|string|number} date2 - 第二个日期 * @param {string} [unit='days'] - 计算单位 ('days', 'hours', 'minutes', 'seconds') * @returns {number} 日期差值 */ function getDateDiff(date1, date2, unit = 'days') { const d1 = new Date(date1); const d2 = new Date(date2); if (isNaN(d1.getTime()) || isNaN(d2.getTime())) { throw new TypeError('Invalid date'); } const diffMs = Math.abs(d2.getTime() - d1.getTime()); switch (unit) { case 'days': return Math.floor(diffMs / (1000 * 60 * 60 * 24)); case 'hours': return Math.floor(diffMs / (1000 * 60 * 60)); case 'minutes': return Math.floor(diffMs / (1000 * 60)); case 'seconds': return Math.floor(diffMs / 1000); default: throw new Error(`Unsupported unit: ${unit}`); } } /** * 添加时间 * @param {Date|string|number} date - 原始日期 * @param {number} amount - 数量 * @param {string} [unit='days'] - 单位 ('years', 'months', 'days', 'hours', 'minutes', 'seconds') * @returns {Date} 计算后的日期 */ function addDate(date, amount, unit = 'days') { const d = new Date(date); if (isNaN(d.getTime())) { throw new TypeError('Invalid date'); } switch (unit) { case 'years': d.setFullYear(d.getFullYear() + amount); break; case 'months': d.setMonth(d.getMonth() + amount); break; case 'days': d.setDate(d.getDate() + amount); break; case 'hours': d.setHours(d.getHours() + amount); break; case 'minutes': d.setMinutes(d.getMinutes() + amount); break; case 'seconds': d.setSeconds(d.getSeconds() + amount); break; default: throw new Error(`Unsupported unit: ${unit}`); } return d; } /** * 获取日期范围 * @param {Date|string|number} startDate - 开始日期 * @param {Date|string|number} endDate - 结束日期 * @param {string} [unit='days'] - 单位 * @returns {Array<Date>} 日期范围数组 */ function getDateRange(startDate, endDate, unit = 'days') { const start = new Date(startDate); const end = new Date(endDate); if (isNaN(start.getTime()) || isNaN(end.getTime())) { throw new TypeError('Invalid date'); } const dates = []; let current = new Date(start); while (current <= end) { dates.push(new Date(current)); current = addDate(current, 1, unit); } return dates; } /** * 获取相对时间描述 * @param {Date|string|number} date - 日期 * @param {Date|string|number} [baseDate=new Date()] - 基准日期 * @returns {string} 相对时间描述 */ function getRelativeTime(date, baseDate = new Date()) { const target = new Date(date); const base = new Date(baseDate); if (isNaN(target.getTime()) || isNaN(base.getTime())) { throw new TypeError('Invalid date'); } const diffMs = target.getTime() - base.getTime(); const diffDays = Math.floor(Math.abs(diffMs) / (1000 * 60 * 60 * 24)); const diffHours = Math.floor(Math.abs(diffMs) / (1000 * 60 * 60)); const diffMinutes = Math.floor(Math.abs(diffMs) / (1000 * 60)); if (diffMs < 0) { // 过去的时间 if (diffDays > 7) { return formatDate(target, 'YYYY-MM-DD'); } else if (diffDays > 0) { return `${diffDays}天前`; } else if (diffHours > 0) { return `${diffHours}小时前`; } else if (diffMinutes > 0) { return `${diffMinutes}分钟前`; } else { return '刚刚'; } } else { // 未来的时间 if (diffDays > 7) { return formatDate(target, 'YYYY-MM-DD'); } else if (diffDays > 0) { return `${diffDays}天后`; } else if (diffHours > 0) { return `${diffHours}小时后`; } else if (diffMinutes > 0) { return `${diffMinutes}分钟后`; } else { return '现在'; } } } /** * 检查是否为同一天 * @param {Date|string|number} date1 - 第一个日期 * @param {Date|string|number} date2 - 第二个日期 * @returns {boolean} 是否为同一天 */ function isSameDay(date1, date2) { const d1 = new Date(date1); const d2 = new Date(date2); if (isNaN(d1.getTime()) || isNaN(d2.getTime())) { throw new TypeError('Invalid date'); } return ( d1.getFullYear() === d2.getFullYear() && d1.getMonth() === d2.getMonth() && d1.getDate() === d2.getDate() ); } /** * 检查是否为今天 * @param {Date|string|number} date - 日期 * @returns {boolean} 是否为今天 */ function isToday(date) { return isSameDay(date, new Date()); } /** * 检查是否为昨天 * @param {Date|string|number} date - 日期 * @returns {boolean} 是否为昨天 */ function isYesterday(date) { const yesterday = addDate(new Date(), -1, 'days'); return isSameDay(date, yesterday); } /** * 检查是否为明天 * @param {Date|string|number} date - 日期 * @returns {boolean} 是否为明天 */ function isTomorrow(date) { const tomorrow = addDate(new Date(), 1, 'days'); return isSameDay(date, tomorrow); } /** * 获取月份天数 * @param {number} year - 年份 * @param {number} month - 月份 (1-12) * @returns {number} 该月的天数 */ function getDaysInMonth(year, month) { if (month < 1 || month > 12) { throw new Error('Month must be between 1 and 12'); } return new Date(year, month, 0).getDate(); } /** * 获取星期几 * @param {Date|string|number} date - 日期 * @param {string} [locale='zh-CN'] - 语言环境 * @returns {string} 星期几 */ function getDayOfWeek(date, locale = 'zh-CN') { const d = new Date(date); if (isNaN(d.getTime())) { throw new TypeError('Invalid date'); } const options = { weekday: 'long' }; return d.toLocaleDateString(locale, options); } /** * 获取季度 * @param {Date|string|number} date - 日期 * @returns {number} 季度 (1-4) */ function getQuarter(date) { const d = new Date(date); if (isNaN(d.getTime())) { throw new TypeError('Invalid date'); } const month = d.getMonth() + 1; return Math.ceil(month / 3); } /** * 获取年龄 * @param {Date|string|number} birthDate - 出生日期 * @param {Date|string|number} [currentDate=new Date()] - 当前日期 * @returns {number} 年龄 */ function getAge(birthDate, currentDate = new Date()) { const birth = new Date(birthDate); const current = new Date(currentDate); if (isNaN(birth.getTime()) || isNaN(current.getTime())) { throw new TypeError('Invalid date'); } let age = current.getFullYear() - birth.getFullYear(); const monthDiff = current.getMonth() - birth.getMonth(); if (monthDiff < 0 || (monthDiff === 0 && current.getDate() < birth.getDate())) { age--; } return age; } /** * 检查是否为闰年 * @param {number} year - 年份 * @returns {boolean} 是否为闰年 */ function isLeapYear(year) { return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; } /** * 获取时间戳 * @param {Date|string|number} [date=new Date()] - 日期 * @returns {number} 时间戳 */ function getTimestamp(date = new Date()) { const d = new Date(date); if (isNaN(d.getTime())) { throw new TypeError('Invalid date'); } return d.getTime(); } /** * 获取当前时间戳 * @returns {number} 当前时间戳 */ function now() { return Date.now(); } module.exports = { formatDate, parseDate, getDateDiff, addDate, getDateRange, getRelativeTime, isSameDay, isToday, isYesterday, isTomorrow, getDaysInMonth, getDayOfWeek, getQuarter, getAge, isLeapYear, getTimestamp, now, };