import { isDate, isNumber, isString, } from '@/common/utils/types' import { isNumStr } from '@/common/utils/objects.ts' import { type DateObjectUnits, DateTime, } from 'luxon' /* * 文档:https://luxon.nodejs.cn/ */ export class FMT { static readonly month: string = 'yyyy-MM' static readonly date: string = 'yyyy-MM-dd' static readonly time: string = 'HH:mm' static readonly time_sec: string = 'HH:mm:ss' static readonly date_time: string = 'yyyy-MM-dd HH:mm' static readonly date_time_sec: string = 'yyyy-MM-dd HH:mm:ss' static readonly date_zh: string = 'yyyy年MM月dd日' static readonly time_zh: string = 'HH时mm分' static readonly time_sec_zh: string = 'HH时mm分ss秒' static readonly date_time_zh: string = 'yyyy年MM月dd日HH时mm分' static readonly date_time_sec_zh: string = 'yyyy年MM月dd日HH时mm分ss秒' static readonly timestamp: string = 'x' } /** * 获取当前时间 * * @return luxon 库的时间对象 */ function now() { return DateTime.now() } /** * 解析时间 * * @param date JS 时间对象、时间戳(数字、字符串)、时间字符串、时间描述对象 * @param fmt 时间格式(仅时间字符串需要此参数,默认:yyyy-MM-dd HH:mm:ss) * @return luxon 库的时间对象 */ function parse(date: Date | number | string | DateObjectUnits, fmt: string = FMT.date_time_sec) { if (isDate(date)) { return DateTime.fromJSDate(date as Date) } else if (isNumber(date) || isNumStr(date)) { return DateTime.fromMillis(Number(date)) } else if (isString(date)) { return DateTime.fromFormat(date as string, fmt) } else { return DateTime.fromObject(date as DateObjectUnits) } } /** * 格式化时间 * * @param date luxon 库的时间对象、JS 时间对象 * @param fmt 时间格式(仅时间字符串需要此参数,默认:yyyy-MM-dd HH:mm:ss) */ function format(date?: DateTime | Date, fmt: string = FMT.date_time_sec) { if (date == null) return '' if (isDate(date)) { return DateTime.fromJSDate(date as Date).toFormat(fmt) } else { return (date as DateTime).toFormat(fmt) } } /** * 时间美化(如:1年前) * * @param date luxon 库的时间对象、JS 时间对象、时间戳(数字、字符串)、时间字符串、时间描述对象 * @param other 另一个时间 */ function pretty(date: DateTime | Date | number | string, other: DateTime | Date | number | string = DateTime.now()) { if (!(date instanceof DateTime)) { date = parse(date) } if (!(other instanceof DateTime)) { other = parse(other) } let { seconds, minutes, hours, days, weeks, months, years, } = date.diff(other, [ 'seconds', 'minutes', 'hours', 'days', 'weeks', 'months', 'years' ]) if (years > 0) { return `${years}年后` } else if (years < 0) { return `${-years}年前` } if (months > 0) { return `${months}个月后` } else if (months < 0) { return `${-months}个月前` } if (weeks > 0) { return `${weeks}周后` } else if (weeks < 0) { return `${-weeks}周前` } if (days > 0) { return `${days}天后` } else if (days < 0) { return `${-days}天前` } if (hours > 0) { return `${hours}小时后` } else if (hours < 0) { return `${-hours}小时前` } if (minutes > 0) { return `${minutes}分钟后` } else if (minutes > -5 && minutes <= -1) { return '刚刚' } else if (minutes <= -5) { return `${-minutes}分钟前` } if (seconds > 0) { return '片刻后' } else if (seconds < 0) { return '刚刚' } return '现在' } function prettyDuration(date: DateTime | Date | number | string, other: DateTime | Date | number | string = DateTime.now()) { if (!(date instanceof DateTime)) { date = parse(date) } if (!(other instanceof DateTime)) { other = parse(other) } let { seconds, minutes, hours, days, weeks, months, years, } = date.diff(other, [ 'seconds', 'minutes', 'hours', 'days', 'weeks', 'months', 'years' ]) if (years > 0) { return `${years}年` } else if (years < 0) { return `${-years}年` } if (months > 0) { return `${months}个月` } else if (months < 0) { return `${-months}个月` } if (weeks > 0) { return `${weeks}周` } else if (weeks < 0) { return `${-weeks}周` } if (days > 0) { return `${days}天` } else if (days < 0) { return `${-days}天` } if (hours > 0) { return `${hours}小时` } else if (hours < 0) { return `${-hours}小时` } if (minutes > 0) { return `${minutes}分钟` } else if (minutes < 0) { return `${minutes}分钟` } if (seconds > 0) { return `${seconds}秒` } else { return '小于 1 秒' } } function endOfMonth(date?: DateTime) { if (date == null) { return date = now() } return date.endOf('month') } function beginOfMonth(date?: DateTime) { if (date == null) { return date = now() } return date.startOf('month') } function toDate(date: DateTime) { return date.toJSDate() } export default { now, parse, format, pretty, FMT, endOfMonth, beginOfMonth, toDate, prettyDuration, }