import Toolkit from "./Toolkit"; import Text from "./Text"; export default class Time { /** 1 秒时间戳 */ public static S = 1E3; /** 1 分钟时间戳 */ public static M = Time.S * 60; /** 1 小时时间戳 */ public static H = Time.M * 60; /** 1 天时间戳 */ public static D = Time.H * 24; public static now(): number { return new Date().getTime(); } public static toTimestamp(date: Date): number { return date.getTime(); } public static toDateObject(unix?: number): Date | undefined { if (!unix) { return undefined; } return new Date(unix); } public static formatDate(date: Date): string { return `${date.getFullYear()}-${Text.pad(date.getMonth() + 1)}-${Text.pad(date.getDate())}`; } public static formatDateTime(date: Date): string { return `${this.formatDate(date)} ${Text.pad(date.getHours())}:${Text.pad(date.getMinutes())}`; } /** * Unix 时间戳转日期 * * @param unix 时间戳 */ public static toDate(unix?: number): string { if (!unix) return ""; return this.formatDate(new Date(unix)); } /** * Unix 时间戳转时间 * * @param unix 时间戳 */ public static toTime(unix?: number): string { if (!unix) return ""; const d = new Date(unix); return `${Text.pad(d.getHours())}:${Text.pad(d.getMinutes())}`; } public static toShortTime(unix?: number): string { if (!unix) return ""; const d = new Date(unix); return `${Text.pad(d.getMinutes())}:${Text.pad(d.getSeconds())}`; } /** * Unix 时间戳转日期和时间 * * @param unix 时间戳 */ public static toDateTime(unix?: number): string { if (!unix) return ""; return `${this.toDate(unix)} ${this.toTime(unix)}`; } public static toPassedDate(unix?: number): string { return this.toPassedDateTime(unix, false); } public static toPassedDateTime(unix?: number, withDetailTime = true): string { if (!unix) { return ""; } const now = new Date().getTime(); const between = now - unix; if (Time.D * 4 <= between) { return withDetailTime ? this.toDateTime(unix) : this.toDate(unix); } else if (Time.D < between) { return `${Math.floor(between / Time.D)} 天前`; } else if (Time.H < between) { return `${Math.floor(between / Time.H)} 小时前`; } else if (Time.M < between) { return `${Math.floor(between / Time.M)} 分钟前`; } else { return "刚刚"; } } public static between(begin: Date, end?: Date) : any { if (!end) { end = new Date(); } const cs = 1000, cm = 6E4, ch = 36E5, cd = 864E5, cy = 31536E6; const l = end.getTime() - begin.getTime(); const y = Math.floor(l / cy), d = Math.floor((l / cd) - y * 365), h = Math.floor((l - (y * 365 + d) * cd) / ch), m = Math.floor((l - (y * 365 + d) * cd - h * ch) / cm), s = Math.floor((l - (y * 365 + d) * cd - h * ch - m * cm) / cs), ms = Math.floor(((l - (y * 365 + d) * cd - h * ch - m * cm) / cs - s) * cs); return { l, y, d, h, m, s, ms }; } public static duration(totalMs?: number | null | undefined, ms?: boolean): string { if (totalMs === null || totalMs === undefined) { return ""; } let remain = Math.floor(totalMs); const yearMs = Time.D * 365; const dayMs = Time.D; const hourMs = Time.H; const minuteMs = Time.M; const secondMs = Time.S; const years = Math.floor(remain / yearMs); remain %= yearMs; const days = Math.floor(remain / dayMs); remain %= dayMs; const hours = Math.floor(remain / hourMs); remain %= hourMs; const minutes = Math.floor(remain / minuteMs); remain %= minuteMs; const seconds = Math.floor(remain / secondMs); remain %= secondMs; const milliseconds = remain; const parts: string[] = []; Toolkit.doWhere(0 < years, () => parts.push(`${years} 年`)); Toolkit.doWhere(0 < days, () => parts.push(`${days} 天`)); Toolkit.doWhere(0 < hours, () => parts.push(`${hours} 小时`)); Toolkit.doWhere(0 < minutes, () => parts.push(`${minutes} 分钟`)); Toolkit.doWhere(0 < seconds, () => parts.push(`${seconds} 秒`)); Toolkit.doWhere(!!ms && 0 < milliseconds, () => parts.push(`${milliseconds} 毫秒`)); return parts.join(" "); } public static toMediaTime(seconds: number): string { seconds = Math.floor(seconds); const hours = Math.floor(seconds / 3600); const minutes = Math.floor((seconds % 3600) / 60); const second = seconds % 60; if (0 < hours) { return `${hours}:${Text.pad(minutes)}:${Text.pad(second)}`; } return `${Text.pad(minutes)}:${Text.pad(second)}`; } /** * 将时间字符串解析为毫秒值 * *

支持的格式示例: *

	 * 10               = 10
	 * 10ms             = 10
	 * 10s              = 10,000
	 * 10m              = 600,000
	 * 10h              = 36,000,000
	 * 10d = 10D = 10 d = 864,000,000
	 * 10.5d            = 907,200,000
	 * 
* * @param timeStr 时间字符串 * @return 毫秒 * @throws Error 输入格式无效 */ public static parseToMS(timeStr: string): number { if (!timeStr || timeStr.trim() === "") { throw new Error("not found timeStr"); } const normalized = timeStr.replace(/\s+/g, "").toLowerCase(); const pattern = /^(\d+(?:\.\d+)?)(ms|[dhms])?$/; const matcher = pattern.exec(normalized); if (!matcher) { throw new Error("invalid format: " + timeStr); } const value = parseFloat(matcher[1]); const unit = matcher[2]; if (!unit || unit === "ms") { return Math.round(value); } let multiplier: number; switch (unit) { case "s": multiplier = Time.S; break; case "m": multiplier = Time.M; break; case "h": multiplier = Time.H; break; case "d": multiplier = Time.D; break; default: throw new Error("invalid format unit: " + unit); } return Math.round(value * multiplier); } }