import dayjs from "dayjs"; /** * 安全地将字符串转换为 Date 对象,兼容 iOS * iOS 不支持 "yyyy-MM-dd HH:mm:ss" 格式,需要转换为 "yyyy-MM-ddTHH:mm:ss" 或 "yyyy/MM/dd HH:mm:ss" * @param dateStr 日期字符串 * @returns Date 对象 */ const parseDate = (dateStr: string): Date => { if (!dateStr) return new Date(); // 将 "yyyy-MM-dd HH:mm:ss" 格式转换为 "yyyy-MM-ddTHH:mm:ss" (ISO 8601) // 替换第一个空格为 T const isoStr = dateStr.replace(/^(\d{4}-\d{2}-\d{2})\s(\d{2}:\d{2}(?::\d{2})?)$/, '$1T$2'); return new Date(isoStr); }; /** * 获取下一个整点时间 * @returns 格式为 YYYY-MM-DD HH:mm 的字符串 */ export const getNextHourTime = (): string => { const now = dayjs(); const nextHour = now.add(1, "hour").startOf("hour"); return nextHour.format("YYYY-MM-DD HH:mm"); }; /** * 根据开始时间计算结束时间(2小时后) * @param startTime 开始时间,格式为 YYYY-MM-DD HH:mm * @returns 格式为 YYYY-MM-DD HH:mm 的字符串 */ export const getEndTime = (startTime: string): string => { const startDateTime = dayjs(startTime); const endDateTime = startDateTime.add(2, "hour"); return endDateTime.format("YYYY-MM-DD HH:mm"); }; export const getDateStr = (date: Date): string => { return dayjs(date).format("YYYY-MM-DD HH:mm"); }; export const getDate = (date: string): string => { return dayjs(date).format("YYYY年MM月DD日"); }; export const getDay = (date?: string | Date): string => { if (!date) { return dayjs().format("YYYY-MM-DD"); } return dayjs(date).format("YYYY-MM-DD"); }; export const getMonth = (date?: string | Date): string => { if (!date) { return dayjs().format("MM月 YYYY"); } return dayjs(date).format("MM月 YYYY"); }; export const getWeekend = (date?: string | Date): [Date, Date] => { const today = dayjs(date); const currentDayOfWeek = today.day(); console.log("currentDayOfWeek", currentDayOfWeek); const saturdayOffset = 6 - currentDayOfWeek; const sundayOffset = 7 - currentDayOfWeek; const sat = today.add(saturdayOffset, "day"); const sun = today.add(sundayOffset, "day"); return [sat.toDate(), sun.toDate()]; }; export const getWeekendOfCurrentWeek = (days = 7): Date[] => { const dayList: Date[] = []; for (let i = 0; i < days; i++) { const day = dayjs().add(i, "day").toDate(); dayList.push(day); } return dayList; }; export const getTime = (time: string): string => { const timeObj = dayjs(time); const hour = timeObj.hour(); const minute = timeObj.minute(); // 判断是上午还是下午 const period = hour <= 12 ? "AM" : "PM"; // 转换为12小时制 const hour12 = hour === 0 ? 0 : hour > 12 ? hour - 12 : hour; // 格式化分钟,保证两位数 const minuteStr = minute.toString().padStart(2, "0"); return `${hour12}:${minuteStr} ${period}`; }; /** * 格式化时间显示(相对时间) * @param timeStr 时间字符串 * @returns 格式化后的时间字符串 */ export const formatRelativeTime = (timeStr: string): string => { if (!timeStr) return ""; const date = parseDate(timeStr); const now = new Date(); // 获取日期部分(年-月-日),忽略时间 const getDateString = (d: Date) => { const year = d.getFullYear(); const month = d.getMonth() + 1; const day = d.getDate(); return `${year}-${month.toString().padStart(2, "0")}-${day .toString() .padStart(2, "0")}`; }; const dateStr = getDateString(date); const nowStr = getDateString(now); // 计算日期差 const dateObj = new Date(dateStr); const nowObj = new Date(nowStr); const diffTime = nowObj.getTime() - dateObj.getTime(); const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24)); if (diffDays === 0) { // 今天 const hours = date.getHours(); const minutes = date.getMinutes(); return `今天 ${hours.toString().padStart(2, "0")}:${minutes .toString() .padStart(2, "0")}`; } else if (diffDays === 1) { // 昨天 const hours = date.getHours(); const minutes = date.getMinutes(); return `昨天 ${hours.toString().padStart(2, "0")}:${minutes .toString() .padStart(2, "0")}`; } else if (diffDays < 7) { // 一周内显示天数 return `${diffDays}天前`; } else { // 超过一周显示完整日期 const year = date.getFullYear(); const month = date.getMonth() + 1; const day = date.getDate(); const hours = date.getHours(); const minutes = date.getMinutes(); return `${year}-${month.toString().padStart(2, "0")}-${day .toString() .padStart(2, "0")} ${hours.toString().padStart(2, "0")}:${minutes .toString() .padStart(2, "0")}`; } }; /** * 格式化时间显示(简短相对时间) * @param timeStr 时间字符串 * @returns 格式化后的时间字符串 */ export const formatShortRelativeTime = (timeStr: string): string => { if (!timeStr) return ""; const date = parseDate(timeStr); const now = new Date(); // 获取日期部分(年-月-日),忽略时间 const getDateString = (d: Date) => { const year = d.getFullYear(); const month = d.getMonth() + 1; const day = d.getDate(); return `${year}-${month.toString().padStart(2, "0")}-${day .toString() .padStart(2, "0")}`; }; const dateStr = getDateString(date); const nowStr = getDateString(now); // 计算日期差 const dateObj = new Date(dateStr); const nowObj = new Date(nowStr); const diffTime = nowObj.getTime() - dateObj.getTime(); const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24)); // 如果是今天,显示具体时间 if (diffDays === 0) { const diff = now.getTime() - date.getTime(); const minutes = Math.floor(diff / (1000 * 60)); const hours = Math.floor(diff / (1000 * 60 * 60)); if (minutes < 1) { return "刚刚"; } else if (minutes < 60) { return `${minutes}分钟前`; } else { return `${hours}小时前`; } } else if (diffDays === 1) { return "1天前"; } else if (diffDays < 7) { return `${diffDays}天前`; } else { const month = date.getMonth() + 1; const day = date.getDate(); return `${month}月${day}日`; } }; /** * 格式化球局时间显示(例如:明天(周五)下午5点) * @param timeStr 时间字符串 * @returns 格式化后的时间字符串 */ export const formatGameTime = (timeStr: string): string => { if (!timeStr) return ""; const date = parseDate(timeStr); const now = new Date(); // 获取星期几 const weekDays = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"]; const weekDay = weekDays[date.getDay()]; // 获取小时和分钟 const hours = date.getHours(); const minutes = date.getMinutes(); // 判断上午/下午/晚上 let period = ""; let displayHour = hours; if (hours >= 0 && hours < 6) { period = "凌晨"; } else if (hours >= 6 && hours < 12) { period = "上午"; } else if (hours >= 12 && hours < 18) { period = "下午"; displayHour = hours === 12 ? 12 : hours - 12; } else { period = "晚上"; displayHour = hours - 12; } // 格式化时间部分 const timeStr2 = minutes === 0 ? `${displayHour}点` : `${displayHour}点${minutes}分`; // 获取日期部分(年-月-日),忽略时间 const getDateString = (d: Date) => { const year = d.getFullYear(); const month = d.getMonth() + 1; const day = d.getDate(); return `${year}-${month.toString().padStart(2, "0")}-${day .toString() .padStart(2, "0")}`; }; const dateStr = getDateString(date); const nowStr = getDateString(now); // 计算日期差 const dateObj = new Date(dateStr); const nowObj = new Date(nowStr); const diffTime = dateObj.getTime() - nowObj.getTime(); const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24)); // 根据日期差返回不同格式 if (diffDays === 0) { // 今天 return `今天(${weekDay})${period}${timeStr2}`; } else if (diffDays === 1) { // 明天 return `明天(${weekDay})${period}${timeStr2}`; } else if (diffDays === 2) { // 后天 return `后天(${weekDay})${period}${timeStr2}`; } else if (diffDays > 2 && diffDays <= 7) { // 一周内 return `${weekDay}${period}${timeStr2}`; } else { // 超过一周,显示具体日期 const month = date.getMonth() + 1; const day = date.getDate(); return `${month}月${day}日(${weekDay})${period}${timeStr2}`; } }; /** * 计算时长(结束时间 - 开始时间) * @param startTime 开始时间字符串 * @param endTime 结束时间字符串 * @returns 格式化后的时长字符串(如:2小时、1.5小时、30分钟) */ export const calculateDuration = ( startTime: string, endTime: string ): string => { if (!startTime || !endTime) return ""; const start = parseDate(startTime); const end = parseDate(endTime); // 计算时间差(毫秒) const diffMs = end.getTime() - start.getTime(); // 转换为分钟 const diffMinutes = Math.floor(diffMs / (1000 * 60)); // 转换为小时 const hours = Math.floor(diffMinutes / 60); const minutes = diffMinutes % 60; // 格式化输出 if (hours > 0 && minutes > 0) { return `${hours}.5小时`; } else if (hours > 0) { return `${hours}小时`; } else if (minutes > 0) { return `${minutes}分钟`; } else { return ""; } }; export const getOneMonth = (): Date[] => { const dates: Date[] = []; const currentDate = dayjs(); const nextMonth = dayjs().add(1, "month"); // 从当前日期开始,遍历到下个月的同一天 let date = currentDate; while (date.isBefore(nextMonth) || date.isSame(nextMonth, "day")) { dates.push(date.toDate()); date = date.add(1, "day"); } return dates; };