js 微信聊天框的时间显示规则,以及输出的时间格式(已优化)

第一版:(在时间过渡的时候,优先判断显示“年月”的时间,后判断显示“昨天”的时间)

已纠正月底到月初展示的时间,优先展示有月份的时间,也就是下面的“今年消息”,不优先展示“昨天消息”。由于产品考虑到用户对于昨天消息的在年份或月份过渡的时候不好判断,不是很清楚昨天的时间到底是几年几月几日的时候,这个时候还需要用户手动去查日历,就不是很方便,所以就改成了这样。

代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
</body>
</html>
<script src="./dayjs.min.js"></script>
<script>
//新消息,不显示
//当天消息,显示:10:22
//昨天消息,显示:昨天 20:41
//今年消息,上午下午,显示:3月17日 下午16:45
//其他消息,上午下午,显示:2020年11月2日 下午15:17

/*不显示的条件*/
// 新消息(小于5分钟)
// 当天的消息(间隔不大于等于5分钟)

var list=[{
    msg:'今天也很nice',
    date:'2019-12-31 23:11'
},{
    msg:'吃饭了吗?',
    date:'2020-01-01 06:00'
},{
    msg:'没有吃饭',
    date:'2021-02-28 13:30'
},{
    msg:'记得吃饭',
    date:'2021-03-01 10:18'
},{
    msg:'那就煮饭',
    date:'2021-05-31 11:11'
},{
    msg:'没米了',
    date:'2021-06-01 05:59'
},{
    msg:'吃空气吧',
    date:'2021-06-01 06:01'
},{
    msg:'没有饭了',
    date:'2021-06-01 08:23'
}];

console.log(checkShowRule(list,'date'));
//循环处理时间
/**
 * 参数
 * arr:数据数组
 * key:数组中对象的时间key键。
 * 新增属性
 * show_time_type:时间的类型
 * show_time:页面展示输出的时间
 * is_show_time:间隔上个时间是否大于5分钟,大于则显示当前时间,反之。
 **/
function checkShowRule(arr,key){
    var newArr=arr.map((item,index,array)=>{
        var obj=toggleTime(item[key]);
        item['show_time_type']=obj.type;
        item['show_time']=obj.time;
        if(index>0){
            item['is_show_time']=compareTimeInterval(array[index-1][key],array[index][key]);
        }else{
            item['is_show_time']=true;
        }
        return item;
    });
    return newArr;
}
//根据不同时间的消息,输出不同的时间格式
function toggleTime(date){
    var time;
    var type=getDateDiff(date);
    //1:新消息,2:当天消息,3:昨天消息,4:今年消息,5:其他消息
    if(type==1){
        time="以下为最新消息";//新消息,不显示时间,但是要显示"以下为最新消息"
    }else if(type==2){
        time=dayjs(date).format("H:mm");//当天消息,显示:10:22
    }else if(type==3){
        time=dayjs(date).format("昨天 H:mm");//昨天消息,显示:昨天 20:41
    }else if(type==4){
        time=dayjs(date).format("M月D日 AH:mm").replace("AM","上午").replace("PM","下午");//今年消息,上午下午,显示:3月17日 下午16:45
    }else if(type==5){
        time=dayjs(date).format("YYYY年M月D日 AH:mm").replace("AM","上午").replace("PM","下午");//其他消息,上午下午,显示:2020年11月2日 下午15:17
    }
    return {
        time:time,
        type:type
    };
}
//判断消息类型
function getDateDiff(date) {
    var nowDate=dayjs(new Date());//当前时间
    var oldDate=dayjs(new Date(date));//参数时间
    var result;
    if (nowDate.year()-oldDate.year() >= 1) {
        result=5;
    } else if (nowDate.month()-oldDate.month()>=1 || nowDate.date()-oldDate.date()>=2) {
        result=4;
    } else if (nowDate.date()-oldDate.date()>=1) {
        result=3;
    } else if (nowDate.hour()-oldDate.hour()>=1 || nowDate.minute()-oldDate.minute()>=5) {
        result=2;
    } else {
        result=1;
    }
    return result;
}

//判断两个时间差是否大于5分钟
function compareTimeInterval(t1,t2){
    // console.log(t1,t2,dayjs(t2)-dayjs(t1));
    return dayjs(t2)-dayjs(t1)>=300000?true:false;
}
</script>

运行时间:2021-06-01 10:33,“那就煮饭”那条消息是两个版本的差异,输出:

返回的关键词使用说明:

is_show_time:用来判断是否显示这条消息的时间。true:显示,false:不显示

show_time:格式化后的时间。不同时间段距离当前时间的不同,显示格式也不一样。

show_time_type:格式化时间的类型。如果有需要的地方可以使用来做其他判断。

第二版:(在时间过渡的时候,优先判断显示“昨天”的时间,后判断显示“年月”的时间)(这个版本与微信显示逻辑相似)

代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
</body>
</html>
<script src="./dayjs.min.js"></script>
<script>
//新消息,不显示
//当天消息,显示:10:22
//昨天消息,显示:昨天 20:41
//今年消息,上午下午,显示:3月17日 下午16:45
//其他消息,上午下午,显示:2020年11月2日 下午15:17

/*不显示的条件*/
// 新消息(小于5分钟)
// 当天的消息(间隔不大于等于5分钟)

var list=[{
    msg:'今天也很nice',
    date:'2019-12-31 23:11'
},{
    msg:'吃饭了吗?',
    date:'2020-01-01 06:00'
},{
    msg:'没有吃饭',
    date:'2021-02-28 13:30'
},{
    msg:'记得吃饭',
    date:'2021-03-01 10:18'
},{
    msg:'那就煮饭',
    date:'2021-05-31 11:11'
},{
    msg:'没米了',
    date:'2021-06-01 05:59'
},{
    msg:'吃空气吧',
    date:'2021-06-01 06:01'
},{
    msg:'没有饭了',
    date:'2021-06-01 08:23'
}];

console.log(checkShowRule(list,'date'));
//循环处理时间
/**
 * 参数
 * arr:数据数组
 * key:数组中对象的时间key键。
 * 新增属性
 * show_time_type:时间的类型
 * show_time:页面展示输出的时间
 * is_show_time:间隔上个时间是否大于5分钟,大于则显示当前时间,反之。
 **/
function checkShowRule(arr,key){
    var newArr=arr.map((item,index,array)=>{
        var obj=toggleTime(item[key]);
        item['show_time_type']=obj.type;
        item['show_time']=obj.time;
        if(index>0){
            item['is_show_time']=compareTimeInterval(array[index-1][key],array[index][key]);
        }else{
            item['is_show_time']=true;
        }
        return item;
    });
    return newArr;
}
//根据不同时间的消息,输出不同的时间格式
function toggleTime(date){
    var time;
    var type=getDateDiff(date);
    //1:新消息,2:当天消息,3:昨天消息,4:今年消息,5:其他消息
    if(type==1){
        time="以下为最新消息";//新消息,不显示时间,但是要显示"以下为最新消息"
    }else if(type==2){
        time=dayjs(date).format("H:mm");//当天消息,显示:10:22
    }else if(type==3){
        time=dayjs(date).format("昨天 H:mm");//昨天消息,显示:昨天 20:41
    }else if(type==4){
        time=dayjs(date).format("M月D日 AH:mm").replace("AM","上午").replace("PM","下午");//今年消息,上午下午,显示:3月17日 下午16:45
    }else if(type==5){
        time=dayjs(date).format("YYYY年M月D日 AH:mm").replace("AM","上午").replace("PM","下午");//其他消息,上午下午,显示:2020年11月2日 下午15:17
    }
    return {
        time:time,
        type:type
    };
}
//判断消息类型
function getDateDiff(date) {
    var nowDate=dayjs(new Date());//当前时间
    var oldDate=dayjs(new Date(date));//参数时间
    var timeTemp=dayjs(getThisTime().now.split(" ")[0]+"00:00").diff(oldDate,'hour');
    var result;
    //优先判断昨天消息。今年的日期00:00的时间与上一个时间的时间戳小于1天,那就判断为昨天消息
    if((nowDate.year()-oldDate.year() == 1 || nowDate.month()-oldDate.month()==1) && timeTemp>=0 && timeTemp<=24){       
        result=3;
    }else if (nowDate.year()-oldDate.year() >= 1) {
        result=5;
    }else if (nowDate.month()-oldDate.month()>=1 || nowDate.date()-oldDate.date()>=2) {
        result=4;
    } else if (nowDate.date()-oldDate.date()>=1) {
        result=3;
    } else if (nowDate.hour()-oldDate.hour()>=1 || nowDate.minute()-oldDate.minute()>=5) {
        result=2;
    } else {
        result=1;
    }
    return result;
}

//判断两个时间差是否大于5分钟
function compareTimeInterval(t1,t2){
    // console.log(t1,t2,dayjs(t2)-dayjs(t1));
    return dayjs(t2)-dayjs(t1)>=300000?true:false;
}

//获取当前时间,当前日期
function getThisTime(timeStamp) {
    var myDate = timeStamp ? new Date(parseInt(timeStamp) * 1000) : new Date();
    function p(s) {
        return s < 10 ? '0' + s : s;
    }
    return {
        'year': myDate.getFullYear(),
        'month': myDate.getMonth() + 1,
        'date': myDate.getDate(),
        'h': myDate.getHours(),
        'm': myDate.getMinutes(),
        's': myDate.getSeconds(),
        'now': myDate.getFullYear() + '-' + p(myDate.getMonth() + 1) + "-" + p(myDate.getDate()) + " " + p(myDate.getHours()) + ':' + p(myDate.getMinutes()) + ":" + p(myDate.getSeconds())
    };
}
</script>

运行时间:2021-06-01 11:32,圈中部分是两个版本的差异,输出:

昨天时间的判断逻辑:

今天的日期00:00的时间与传入时间的时间戳,使用dayjs的diff函数对比两个时间相差的小时,大于等于0小时并且小于等于24小时,那就判断为昨天消息。

其他(时间排序):

/**
 * 时间大小排序(比较器)
 * prop:对象数组排序的键
 * align:排序方式,"positive"正序:旧时间在上,新时间在下,"inverted"倒序:新时间在上,旧时间在下。
 * 
 * 调用示例:arr.sort(compare('time','inverted'));
 * 注意:time的格式要求,如果是时间戳,那么不能是字符串类型;如果是“2020-12-15 18:26:00”的格式,无需处理。
 */
function compareAlign(prop,align){
    return function(a,b){
        var value1=a[prop];
        var value2=b[prop];
        if(align=="positive"){//正序
            return new Date(value1)-new Date(value2);
        }else if(align=="inverted"){//倒序
            return new Date(value2)-new Date(value1);
        }
    }
}

调用代码:

list.sort(compareAlign('date','positive'));

如果发现有其他细节上的问题,欢迎指出。

旧版本的代码下载链接,如果不会下载dayjs的可以从这个链接下载:

微信聊天消息列表的时间显示判断.rar_微信聊天-互联网文档类资源-CSDN下载

网络上其他版本:

按返回日期数据显示刚刚,几分钟前/几点几分/今天/昨天/具体日期_chi1130的博客-CSDN博客

export const dateTimeFormat = date => {
  //  auto 0
  const autoZero = (n) => (String(n).length === 1 ? '0' : '') + n
  // string to timestamp
  const strToTimestamp = (str) => Date.parse(str.replace(/-/gi, '/'))
  let oriSecond = strToTimestamp(date) / 1000
  let curSecond = parseInt(new Date().getTime() / 1000)
  let diffSecond = curSecond - oriSecond

  let curDate = new Date(curSecond * 1000)
  let oriDate = new Date(oriSecond * 1000)

  let Y = oriDate.getFullYear()
  let m = oriDate.getMonth() + 1
  let d = oriDate.getDate()
  let H = oriDate.getHours()
 let i = oriDate.getMinutes()

 // just
  if (diffSecond < 60) {
    // within a minute
    return '刚刚'
  } else if (diffSecond < 3600) {
    // within an hour
    return `${Math.floor(diffSecond / 60)}分钟前`
  } else if (
    curDate.getFullYear() === Y &&
  curDate.getMonth() + 1 === m &&
  curDate.getDate() === d
  ) {
    return `今天${autoZero(H)}:${autoZero(i)}`
 }
 // yesterday
 let mewDate = new Date((curSecond - 86400) * 1000)
  if (mewDate.getFullYear() === Y && mewDate.getMonth() + 1 === m && mewDate.getDate() === d) {
    return `昨天${autoZero(H)}:${autoZero(i)}`
  } else if (curDate.getFullYear() === Y) {
    return `${autoZero(m)}月${autoZero(d)}日`
  }
  return `${Y}年${autoZero(m)}月${autoZero(d)}日`
}

评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

草字

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值