java时间与现在做比较展示对应格式描述信息【刚刚,几分钟,几小时前,几天前,xx年xx月xx日】

9 篇文章 0 订阅
9 篇文章 0 订阅

视频讲解

哔哩哔哩视频讲解

实现效果

在这里插入图片描述

简述

今天遇到一个需求,就是将消息的创建时间与当前时间做比较,展示对应的数据格式,具体要求如下:

1. 1分钟内:刚刚              
2. 60分钟内:x分钟前           
3. 24小时内:x小时前           
4. >24小时:x月x日  08-1     
5. 非年内:年--2021-05-02 

实现思路

从需求描述来看,我们很容易可以发现需要比较的时间的最小精度是【秒】,所以我们具体操作可以这样做

  1. 先取得年份,比较是否在年内
  2. 当前时间与传入时间比较取得秒数差
  3. 比较60秒内显示刚刚
  4. 秒数差 < 60*60 (即60分钟) => 秒数差/60 分钟前
  5. 秒数差 < 606024 (即24小时内) => 秒数差/60*60 小时前
  6. 秒数差 >606024 (即24小时内) => 转localDateTime 后再格式化输出 【SimpleDateFormat多线程不安全】

转换成代码如下:
在这里插入图片描述

为了操作方便,也避免计算出错,这里将各个时间单位转换为秒数定义为静态常量,并且使用DateTimFormatter格式化保证多线程安全,如下:
在这里插入图片描述

完整代码

封装DateUtil工具类

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;

/**
 * @Author: lzp
 * @description:
 * @Date: 2022/8/6
 */
public class DateUtils {

    /**
     * 一天、一分钟、一小时对应的秒数
     */
    private static final Long ONE_MINUTE_TO_SECOND = 60L;
    private static final Long ONE_HOUR_TO_SECOND = ONE_MINUTE_TO_SECOND * 60;
    private static final Long ONE_DAY_TO_SECOND = ONE_HOUR_TO_SECOND * 24;

    /**
     * 使用LocalDateTime进行格式化 保证多线程安全
     */
    private static final DateTimeFormatter DATE_TIME_FORMATTER1 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    private static final DateTimeFormatter DATE_TIME_FORMATTER2 = DateTimeFormatter.ofPattern("MM-dd");

    /**
     * 设置推送消息的时间描述
     * 1. 1分钟内:刚刚
     * 2. 60分钟内:x分钟前
     * 3. 24小时内:x小时前
     * 4. >24小时:x月x日  08-1
     * 5. 非年内:年-月-日 2021-05-02
     *
     * @param now        当前时间  传一个当前时间目的是方便遍历,减少date对象的创建
     * @param targetDate 与当前时间做对比的时间
     */
    public static String getTimeDescriptionByDate(Date now, Date targetDate) {
        String timeDescription = "";
        if (targetDate != null) {
            // 5. 年内判断
            if (targetDate.getYear() == now.getYear()) {
                // 获取秒数差
                long betweenSeconds = (now.getTime() - targetDate.getTime()) / 1000;
                if (betweenSeconds < ONE_MINUTE_TO_SECOND) {
                    // 1. 1分钟内:刚刚
                    timeDescription = "刚刚";
                } else if (betweenSeconds < ONE_HOUR_TO_SECOND) {
                    // 2. 60分钟内
                    timeDescription = betweenSeconds / ONE_MINUTE_TO_SECOND + "分钟前";
                } else if (betweenSeconds < ONE_HOUR_TO_SECOND * 24) {
                    // 3. 24小时内:x小时前
                    timeDescription = betweenSeconds / ONE_HOUR_TO_SECOND + "小时前";
                } else {
                    // 4. >24小时:x月x日  08-1
                    timeDescription = dateToLocalDateTime(targetDate).format(DATE_TIME_FORMATTER2);
                }
            } else {
                timeDescription = dateToLocalDateTime(targetDate).format(DATE_TIME_FORMATTER1);
            }
        }
        return timeDescription;
    }

    /**
     * date转localDateTime
     */
    public static LocalDateTime dateToLocalDateTime(Date date) {
        return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
    }

}

测试类,直接运行即可,能够自动按照当前时间显示对应的描述:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @Author: lzp
 * @description:
 * @Date: 2022/8/6
 */
public class Demo {
    public static void main(String[] args) throws ParseException {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date now = new Date();
        Calendar cal = Calendar.getInstance();
        cal.setTime(now);
        System.out.printf("当前时间为:%s ==============================\n", df.format(now));
        cal.add(Calendar.SECOND, -20); // 20秒前
        System.out.printf("%s => %s\n", df.format(cal.getTime()), DateUtils.getTimeDescriptionByDate(now, cal.getTime()));
        cal.add(Calendar.MINUTE, -1); // 1分钟前
        System.out.printf("%s => %s\n", df.format(cal.getTime()), DateUtils.getTimeDescriptionByDate(now, cal.getTime()));
        cal.add(Calendar.HOUR, -1); // 1小时前
        System.out.printf("%s => %s\n", df.format(cal.getTime()), DateUtils.getTimeDescriptionByDate(now, cal.getTime()));
        cal.add(Calendar.DAY_OF_MONTH, -1); // 1天前
        System.out.printf("%s => %s\n", df.format(cal.getTime()), DateUtils.getTimeDescriptionByDate(now, cal.getTime()));
        cal.add(Calendar.YEAR, -1); // 1年前
        System.out.printf("%s => %s\n", df.format(cal.getTime()), DateUtils.getTimeDescriptionByDate(now, cal.getTime()));
    }
}

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值