You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现按时间显示今日/昨日/指定日期文本?求代码优化方案

问题分析与代码优化

原代码的核心问题

  • "今日"判断完全失效:直接将传入的time与calendar.timeInMillis(当前系统精确到毫秒的时间)做相等比较,实际场景中几乎不可能触发,无法识别当天任意时刻的时间。
  • "昨日"判断逻辑错误:(time - 86400000)是数值计算而非判断条件,写法完全不符合逻辑,无法正确识别昨日的时间范围。
  • 性能与线程安全隐患:每次调用方法都创建SimpleDateFormat实例,既浪费资源,且该类非线程安全,多线程环境下易出异常。

优化后的实现方案(推荐)

使用Java 8+的java.time API(Kotlin原生兼容),该API线程安全、逻辑直观,能准确处理日期范围判断:

import java.time.LocalDate
import java.time.ZoneId
import java.time.format.DateTimeFormatter
import java.util.Locale

object DateTimeUtils {
    // 提前初始化线程安全的日期格式化器
    private val dateFormatter = DateTimeFormatter.ofPattern("dd MMMM, yyyy", Locale.getDefault())

    fun getDateLabel(timestamp: Long): String {
        // 将时间戳转换为日期(忽略时分秒,只保留年月日)
        val targetDate = LocalDate.ofEpochDay(timestamp / 86400000)
        val today = LocalDate.now(ZoneId.systemDefault())
        val yesterday = today.minusDays(1)

        return when (targetDate) {
            today -> "今日"
            yesterday -> "昨日"
            else -> targetDate.format(dateFormatter)
        }
    }
}

代码说明

  • 精准日期范围判断:通过LocalDate统一忽略时分秒,只比较年月日,确保当天任意时刻都能被识别为"今日",昨日同理。
  • 线程安全与性能:DateTimeFormatter是线程安全的单例实例,避免重复创建带来的性能损耗。
  • 时区适配:使用系统默认时区,确保日期判断符合用户所在地区的时间规则。

兼容旧版本的实现方案(Java 7及以下)

如果项目需兼容低版本Java,可优化原有Calendar逻辑:

import java.util.Calendar
import java.util.Locale
import java.text.SimpleDateFormat

object DateTimeUtils {
    private val dateFormatter = SimpleDateFormat("dd MMMM, yyyy", Locale.getDefault())
    // 同步锁解决SimpleDateFormat线程安全问题
    private val formatterLock = Any()

    fun getDateLabel(timestamp: Long): String {
        // 重置目标时间的时分秒,只保留日期起始点
        val targetCalendar = Calendar.getInstance().apply {
            timeInMillis = timestamp
            set(Calendar.HOUR_OF_DAY, 0)
            set(Calendar.MINUTE, 0)
            set(Calendar.SECOND, 0)
            set(Calendar.MILLISECOND, 0)
        }

        // 生成今日的起始时间
        val todayCalendar = Calendar.getInstance().apply {
            set(Calendar.HOUR_OF_DAY, 0)
            set(Calendar.MINUTE, 0)
            set(Calendar.SECOND, 0)
            set(Calendar.MILLISECOND, 0)
        }

        // 生成昨日的起始时间
        val yesterdayCalendar = Calendar.getInstance().apply {
            timeInMillis = todayCalendar.timeInMillis - 86400000
            set(Calendar.HOUR_OF_DAY, 0)
            set(Calendar.MINUTE, 0)
            set(Calendar.SECOND, 0)
            set(Calendar.MILLISECOND, 0)
        }

        return when (targetCalendar.timeInMillis) {
            todayCalendar.timeInMillis -> "今日"
            yesterdayCalendar.timeInMillis -> "昨日"
            else -> synchronized(formatterLock) {
                dateFormatter.format(timestamp)
            }
        }
    }
}

关键修改点

  • 统一日期起始点:将所有时间的时分秒重置为0,确保比较的是同一天的起始时刻,解决原代码精确毫秒匹配的问题。
  • 线程安全处理:给SimpleDateFormat的格式化操作加同步锁,避免多线程环境下的异常。
  • 逻辑修正:正确计算昨日的起始时间,实现对昨日任意时刻的识别。

内容的提问来源于stack exchange,提问作者Yug Mewada

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 22:33:25