仿微信聊天-时间间隔五分钟

本文介绍了一种用于聊天应用中的时间戳格式化方法,该方法可根据消息发送时间的不同情况展示对应的时间格式,如今天、昨天、本周及更早时间等,并通过实现具体的JavaScript函数来确保时间显示的一致性和用户体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求:

时间显示规则:
5分钟内的消息显示同一个时间,超过5分钟间隔的每条都显示时间(以显示的时间开始计算5分钟,和目前的IM时间显示规则保持一致)

/**
 * 个位数,加0前缀
 * @param {*} number
 * @returns
 */
function addZeroPrefix(number) {
    return number < 10 ? `0${number}` : number
}
/**
 * 返回当天凌晨时间
 * @export
 * @param {*} time
 * @returns
 */
function getTodayTime() {
    const date = new Date()
    const year = date.getFullYear()
    const month = date.getMonth() + 1
    const day = date.getDate()
    const today = `${year}/${month}/${day}`
    const todayTime = new Date(today).getTime() // 当天凌晨的时间
    return todayTime
}
/**
 * 返回年月日
 * @export
 * @param {Date} date
 * @param {string} [splitor='-']
 * @returns
 */
export function getDate(date, splitor = '-') {
    const year = date.getFullYear()
    const month = date.getMonth() + 1
    const day = date.getDate()
    return `${year}${splitor}${addZeroPrefix(month)}${splitor}${addZeroPrefix(day)}`
}

/**
 * 返回时分秒/时分
 * @export
 * @param {*} date
 * @param {boolean} [withSecond=false]
 * @returns
 */
export function getTime(date, withSecond = false) {
    const hour = date.getHours()
    const minute = date.getMinutes()
    const second = date.getSeconds()
    return withSecond
        ? `${addZeroPrefix(hour)}:${addZeroPrefix(minute)}:${addZeroPrefix(second)}`
        : `${addZeroPrefix(hour)}:${addZeroPrefix(minute)}`
}

export function getFullDate(date) {
    return `${getDate(date)} ${getTime(date)}`
}

export function isToday(date) {
    return date.toDateString() === new Date().toDateString()
}

export function isYesterday(time) {
    const todayTime = getTodayTime() // 当天凌晨时间
    const yesterdayTime = new Date(todayTime - 24 * 60 * 60 * 1000).getTime() // 昨天凌晨的时间
    return time < todayTime && yesterdayTime <= time
}

export function isWeek(time) {
    const todayTime = getTodayTime() // 当天凌晨时间
    const lastWeekTime = new Date(todayTime - 24 * 60 * 60 * 1000 * 6).getTime() // 一周前凌晨的时间,因当天凌晨开始算,故*6
    return time < todayTime && lastWeekTime <= time
}

export function NoToday(time, yearTime = false) {
    const data = new Date(time)
    if (isYesterday(time)) {
        return `昨天 ${getTime(time)}`
    }
    if (isWeek(time)) {
        let week

        if (data.getDay() == 0) week = '星期日'

        if (data.getDay() == 1) week = '星期一'

        if (data.getDay() == 2) week = '星期二'

        if (data.getDay() == 3) week = '星期三'

        if (data.getDay() == 4) week = '星期四'

        if (data.getDay() == 5) week = '星期五'

        if (data.getDay() == 6) week = '星期六'

        return `${week} ${getTime(time)}`
    }

    return yearTime ? `${getDate(time)} ${getTime(time)}` : getDate(time)
}
/**
 * 咨询互动-时间格式化(合并)
 * 规则:
 *  1. 每五分钟为一个跨度
 *  2. 今天显示,小时:分钟,例如:11:12
 *  3. 昨天显示,昨天 小时:分钟 例如:昨天 11:12
 *  4. 一周内显示,星期几 小时:分钟 例如:星期四 11:12
 *  5. 日期差大于一周显示,年月日 小时:分钟 例如:2021年9月30日 11:12(时分可控)
 * @param time 传入的当前会话数组
 * @param yearTime 年月日后是否显示 小时:分钟
 * @returns {string|null}
 */
export function timestampFormat(time, yearTime) {
    if (isToday(time)) {
        return getTime(time)
    }
    return NoToday(time, yearTime)
}
/**
 * 咨询互动-聊天时间格式化
 * 规则:
 *  1. 每五分钟为一个跨度
 *  2. 今天显示,小时:分钟,例如:11:12
 *  3. 昨天显示,昨天 小时:分钟 例如:昨天 11:12
 *  4. 一周内显示,星期几 小时:分钟 例如:星期四 11:12
 *  5. 日期差大于一周显示,年月日 小时:分钟 例如:2021年9月30日 11:12
 * @param currentMessageList 传入的当前会话数组
 * @param sort 传入数组排序:0-数组时间倒序;1-数组时间正序
 * @param type 五分钟规则区分:0-永远跟上一个显示的时间对比是否超5分钟 ;1-永远两条消息对比是否超5分钟
 * @returns {Array|null}
 */
export function msgTimeFormat(currentMessageList, sort, type) {
    // console.log('传入的会话数组', currentMessageList)
    const newMessageList = []
    const currentFilterList = currentMessageList.filter((item) => {
        return item.type !== 'showTime'
    })
    currentFilterList.forEach((item, index) => {
        const date = new Date(item.time * 1000)
        let showTime
        if (index === 0) {
            showTime = timestampFormat(date, true)
            // 显示的消息时间
            newMessageList.push({
                payload: {
                    text: showTime
                },
                type: 'showTime',
                time: item.time
            })
            newMessageList.push(item)
        } else if (index <= currentFilterList.length - 1) {
            const current = currentFilterList[index].time
            let minutes
            const showTimeList = newMessageList.filter((item) => {
                return item.type === 'showTime'
            })
            const lastShowTime = showTimeList[showTimeList.length - 1].time
            if (type) {
                const prev = currentFilterList[index - 1].time
                minutes = (current - prev) / 60
            }
            if (!sort) {
                minutes = (current - lastShowTime) / 60
            } else {
                minutes = (lastShowTime - current) / 60
            }
            if (minutes > 5) {
                showTime = timestampFormat(date, true)
                // 显示的消息时间
                newMessageList.push({
                    payload: {
                        text: showTime
                    },
                    type: 'showTime',
                    time: item.time
                })
                newMessageList.push(item)
            } else {
                newMessageList.push(item)
            }
        }
    })
    // console.log('最后得到的数组', newMessageList)
    return newMessageList
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值