Files
uniapp-im-shop/utils/dateUtils.js
bobobobo 9245fefc9a QAQ
2026-02-10 22:58:31 +08:00

176 lines
5.0 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/** 日期格式化 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
}
}