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
JavaScript
// 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,
};