/** 日期格式化 YYYY-MM-DD */ export const formatDate = date => { const d = new Date(date) const year = d.getFullYear() const month = String(d.getMonth() + 1).padStart(2, '0') // 月份从0开始 const day = String(d.getDate()).padStart(2, '0') return `${year}-${month}-${day}` } /** 日期格式化:月.日 */ export const formatMonthDay = date => { // 统一处理为 Date 对象 const d = new Date(date) // 检查是否是有效日期 if (isNaN(d.getTime())) { console.error('Invalid date:', date) return '--.--' } const month = String(d.getMonth() + 1).padStart(2, '0') // getMonth() 是 0-11 const day = String(d.getDate()).padStart(2, '0') return `${month}.${day}` } /** * 将时间字符串转换为相对时间描述 * @param {string} timeStr - 后端返回的时间字符串,如 '2026-01-12 22:51:54' * @returns {string} 相对时间描述,如 '刚刚'、'3分钟前'、'昨天' 等 */ export function formatRelativeTime(timeStr) { // 兼容 iOS 不支持 '-' 分隔的日期格式,需转为标准 ISO 格式 const normalizedTimeStr = timeStr.replace(/-/g, '/') const serverTime = new Date(normalizedTimeStr) const now = new Date() // 时间差(毫秒) const diffMs = now - serverTime // 如果时间在未来,直接返回原始时间或处理异常 if (diffMs < 0) { return timeStr // 或者 return '未来时间'; } const seconds = Math.floor(diffMs / 1000) const minutes = Math.floor(seconds / 60) const hours = Math.floor(minutes / 60) const days = Math.floor(hours / 24) // 判断是否是今天 const isSameDay = (date1, date2) => { return ( date1.getFullYear() === date2.getFullYear() && date1.getMonth() === date2.getMonth() && date1.getDate() === date2.getDate() ) } // 判断是否是昨天 const isYesterday = (date1, date2) => { const yesterday = new Date(date2) yesterday.setDate(date2.getDate() - 1) return isSameDay(date1, yesterday) } if (seconds < 60) { return '刚刚' } else if (minutes < 60) { return `${minutes}分钟前` } else if (hours < 24 && isSameDay(serverTime, now)) { return `${hours}小时前` } else if (isYesterday(serverTime, now)) { return '昨天' } else if (days < 7) { return `${days}天前` } else { // 超过一周,返回原始日期(可选格式化为 YYYY-MM-DD) return timeStr.split(' ')[0] // 或使用更美观的格式 } } /** * 获取天,时,分,秒 * @param {*} dateTimeStr * @returns */ export const parseDateTime = dateTimeStr => { const date = new Date(dateTimeStr) // 检查日期是否有效 if (isNaN(date.getTime())) { throw new Error('Invalid date string') } return { day: date.getDate(), // 月份中的第几天(1-31) hour: date.getHours(), // 小时(0-23) minute: date.getMinutes(), // 分钟(0-59) second: date.getSeconds() // 秒(0-59) } } /** * 计算当前时间距离目标时间的剩余时、分、秒 * @param {string} targetTimeStr - 目标时间字符串,格式如 "2026-02-10 21:50:40" * @returns {Object} 包含hours、minutes、seconds的对象,适配uni-countdown组件 */ export const calculateRemainingTime = targetTimeStr => { // 1. 处理目标时间,转换为时间戳(解决时区问题,手动拆分时间字符串) const [datePart, timePart] = targetTimeStr.split(' ') const [year, month, day] = datePart.split('-').map(Number) const [hour, minute, second] = timePart.split(':').map(Number) // 注意:月份是0开始的,所以要减1 const targetTime = new Date( year, month - 1, day, hour, minute, second ).getTime() // 2. 获取当前时间戳 const currentTime = new Date().getTime() // 3. 计算剩余总秒数(如果目标时间已过,剩余时间为0) let remainingSeconds = Math.max( 0, Math.floor((targetTime - currentTime) / 1000) ) // 4. 转换为时、分、秒 const hours = Math.floor(remainingSeconds / 3600) // 1小时=3600秒 remainingSeconds = remainingSeconds % 3600 // 剩余的秒数 const minutes = Math.floor(remainingSeconds / 60) // 1分钟=60秒 const seconds = remainingSeconds % 60 // 最终剩余的秒数 // 5. 返回适配uni-countdown的格式 return { hours, minutes, seconds } } export const getRemainingTime = endTimeStr => { const now = new Date().getTime() // 当前时间戳(毫秒) const end = new Date(endTimeStr.replace(' ', 'T')).getTime() // 转为 ISO 格式并获取时间戳 if (isNaN(end)) { throw new Error('无效的结束时间格式') } const diff = end - now // 剩余毫秒数 if (diff <= 0) { return { day: 0, hour: 0, minute: 0, second: 0, isExpired: true } } const totalSeconds = Math.floor(diff / 1000) const day = Math.floor(totalSeconds / (24 * 3600)) const hour = Math.floor((totalSeconds % (24 * 3600)) / 3600) const minute = Math.floor((totalSeconds % 3600) / 60) const second = totalSeconds % 60 return { day, hour, minute, second, isExpired: false } }