流水不争先,争的是滔滔不绝

云聊IM即时通讯聊天时间显示格式(Android)[源码]

IM源码 macgrady 177℃

1、引言

即时通讯IM应用中的聊天消息时间显示是个常见需求,作为用户体验来讲,所以时间显示也不该简单显示成电子手表一样“年/月/日 时:分:秒”定式显示。为此开发团队对聊天消息的时间显示格式修改,从而提升用户体验。

作为移动端IM最成功的案例,微信无疑代表着权威,所以本次的消息时间显示格式,直接参照微信的实现逻辑

* 提示:本文中的代码实现,是从 RainbowChat 和 RainbowChat-Web 两个IM产品中扒出来简化后的结果,是基于完全相同的算法逻辑分别用OC、Java和JavaScript实现的。代码仅供参考,不足之外,还请见谅!

2、微信中聊天消息的时间显示规则

先来看看微信中聊天消息的时间显示成什么样:

微信主页“消息”界面

聊天界面(注意聊天界面中默认带了“时:分”的显示)

微信聊天消息时间显示说明

1、当天的消息,以每5分钟为一个跨度的显示时间;
2、消息超过1天、小于1周,显示星期+收发消息的时间;
3、消息大于1周,显示手机收发时间的日期。

3、总结一下微信中聊天消息的时间显示逻辑,根据微信官方的说明,我们可以总结出微信对于聊天消息时间显示的规则

① 微信对于聊天消息时间显示的规则总结如下(首页“消息”界面):

1)当聊天消息时间为一周之内时:当天的消息显示为“小时:分钟”形式,然后是“昨天”、“前天”,然后就是“星期几”这个样子;

2)当聊天消息的时间大于一周时:直接显示“年/月/日”的时间格式。

② 微信对于聊天消息时间显示的规则总结如下(聊天内容界面):

1)当聊天消息时间为一周之内时:当天的消息显示为“小时:分钟”形式,然后是“昨天 时:分”、“前天 时:分”,然后就是“星期几  时:分”这个样子;

2)当聊天消息的时间大于一周时:直接显示“年/月/日 时:分”的完整时间格式。

注意:聊天内容界面里的时间格式,实际上是首页“消息”界面里的时间格式加上“时:分”后的结果,所以代码实现上这两套代码是可以重用。

5、Android平台上的代码实现(标准Java)

/**

 * 返回指定pattern样的日期时间字符串。

 *

 * @param dt

 * @param pattern

 * @return 如果时间转换成功则返回结果,否则返回空字符串””

 * @author 即时通讯网([url=http://www.52im.net]http://www.52im.net[/url])

 */

publicstaticString getTimeString(Date dt, String pattern)

{

        try

        {

                SimpleDateFormat sdf = newSimpleDateFormat(pattern);//”yyyy-MM-dd HH:mm:ss”

                sdf.setTimeZone(TimeZone.getDefault());

                returnsdf.format(dt);

        }

        catch(Exception e)

        {

                return””;

        }

}

/**

* 仿照微信中的消息时间显示逻辑,将时间戳(单位:毫秒)转换为友好的显示格式.

* <p>

* 1)7天之内的日期显示逻辑是:今天、昨天(-1d)、前天(-2d)、星期?(只显示总计7天之内的星期数,即<=-4d);<br>

* 2)7天之外(即>7天)的逻辑:直接显示完整日期时间。

*

* @param srcDate 要处理的源日期时间对象

* @param mustIncludeTime true表示输出的格式里一定会包含“时间:分钟”,否则不包含(参考微信,不包含时分的情况,用于首页“消息”中显示时)

* @return 输出格式形如:“10:30”、“昨天 12:04”、“前天 20:51”、“星期二”、“2019/2/21 12:09”等形式

* @author 即时通讯网([url=http://www.52im.net]http://www.52im.net[/url])

* @since 4.5

*/

publicstaticString getTimeStringAutoShort2(Date srcDate, booleanmustIncludeTime)

{

        String ret = “”;

        try

        {

                GregorianCalendar gcCurrent = newGregorianCalendar();

                gcCurrent.setTime(newDate());

                intcurrentYear = gcCurrent.get(GregorianCalendar.YEAR);

                intcurrentMonth = gcCurrent.get(GregorianCalendar.MONTH)+1;

                intcurrentDay = gcCurrent.get(GregorianCalendar.DAY_OF_MONTH);

                GregorianCalendar gcSrc = newGregorianCalendar();

                gcSrc.setTime(srcDate);

                intsrcYear = gcSrc.get(GregorianCalendar.YEAR);

                intsrcMonth = gcSrc.get(GregorianCalendar.MONTH)+1;

                intsrcDay = gcSrc.get(GregorianCalendar.DAY_OF_MONTH);

                // 要额外显示的时间分钟

                String timeExtraStr = (mustIncludeTime?” “+getTimeString(srcDate, “HH:mm”):””);

                // 当年

                if(currentYear == srcYear)

                {

                        longcurrentTimestamp = gcCurrent.getTimeInMillis();

                        longsrcTimestamp = gcSrc.getTimeInMillis();

                        // 相差时间(单位:毫秒)

                        longdelta = (currentTimestamp – srcTimestamp);

                        // 当天(月份和日期一致才是)

                        if(currentMonth == srcMonth && currentDay == srcDay)

                        {

                                // 时间相差60秒以内

                                if(delta < 60* 1000)

                                           ret = “刚刚”;

                                // 否则当天其它时间段的,直接显示“时:分”的形式

                                else

                                            ret = getTimeString(srcDate, “HH:mm”);

                        }

                        // 当年 && 当天之外的时间(即昨天及以前的时间)

                        else

                        {

                                // 昨天(以“现在”的时候为基准-1天)

                                GregorianCalendar yesterdayDate = newGregorianCalendar();

                                yesterdayDate.add(GregorianCalendar.DAY_OF_MONTH, -1);

                                // 前天(以“现在”的时候为基准-2天)

                                GregorianCalendar beforeYesterdayDate = newGregorianCalendar();

                                beforeYesterdayDate.add(GregorianCalendar.DAY_OF_MONTH, -2);

                                // 用目标日期的“月”和“天”跟上方计算出来的“昨天”进行比较,是最为准确的(如果用时间戳差值

                                // 的形式,是不准确的,比如:现在时刻是2019年02月22日1:00、而srcDate是2019年02月21日23:00,

                                // 这两者间只相差2小时,直接用“delta/(3600 * 1000)” > 24小时来判断是否昨天,就完全是扯蛋的逻辑了)

                                if(srcMonth == (yesterdayDate.get(GregorianCalendar.MONTH)+1)

                                        && srcDay == yesterdayDate.get(GregorianCalendar.DAY_OF_MONTH))

                                {

                                            ret = “昨天”+timeExtraStr;// -1d

                                }

                                // “前天”判断逻辑同上

                                elseif(srcMonth == (beforeYesterdayDate.get(GregorianCalendar.MONTH)+1)

                                        && srcDay == beforeYesterdayDate.get(GregorianCalendar.DAY_OF_MONTH))

                                {

                                            ret = “前天”+timeExtraStr;// -2d

                                }

                                else

                                {

                                            // 跟当前时间相差的小时数

                                            longdeltaHour = (delta/(3600* 1000));

                                            // 如果小于 7*24小时就显示星期几

                                            if(deltaHour < 7*24)

                                            {

                                                String[] weekday = {“星期日”,”星期一”,”星期二”,”星期三”,”星期四”,”星期五”,”星期六”};

                                                // 取出当前是星期几

                                                String weedayDesc = weekday[gcSrc.get(GregorianCalendar.DAY_OF_WEEK)-1];

                                                ret = weedayDesc+timeExtraStr;

                                            }

                                            // 否则直接显示完整日期时间

                                            else

                                                ret = getTimeString(srcDate, “yyyy/M/d”)+timeExtraStr;

                                }

                        }

            }

            else

                ret = getTimeString(srcDate, “yyyy/M/d”)+timeExtraStr;

        }

        catch(Exception e)

        {

                System.err.println(“【DEBUG-getTimeStringAutoShort】计算出错:”+e.getMessage()+” 【NO】”);

        }

        returnret;

}

5.2 调用示例

// 用于首页“消息”界面时

getTimeStringAutoShort2(newDate(), false);

// 用于聊天内容界面时

getTimeStringAutoShort2(newDate(), true);

原文链接:https://blog.csdn.net/hellojackjiang2011/article/details/87894151

版权声明:部分文章、图片等内容为用户发布或互联网整理而来,仅供学习参考。如有侵犯您的版权,请联系我们,将立刻删除。
点击这里给我发消息