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

Android应用中如何根据Locale翻译“Today”“Yesterday”等时间字符串?

嘿,这个需求我之前做项目的时候刚好碰到过,给你几个实用的解决方案:

方案1:使用AndroidX的RelativeDateTimeFormatter(推荐)

AndroidX提供的RelativeDateTimeFormatter是专门解决这类问题的,它原生支持传入Locale参数,而且系统已经帮我们做好了各种语言的翻译适配,不用自己维护多语言字符串。

示例代码(Kotlin):

import androidx.core.text.format.RelativeDateTimeFormatter
import java.util.Locale
import java.util.concurrent.TimeUnit

fun formatRelativeTime(timestamp: Long, targetLocale: Locale): String {
    val formatter = RelativeDateTimeFormatter.getInstance(targetLocale)
    val now = System.currentTimeMillis()
    val timeDiff = now - timestamp

    return when {
        // 小于1分钟
        timeDiff < TimeUnit.MINUTES.toMillis(1) -> {
            formatter.format(timeDiff, RelativeDateTimeFormatter.Direction.NOW, RelativeDateTimeFormatter.Units.SECOND)
        }
        // 小于1小时
        timeDiff < TimeUnit.HOURS.toMillis(1) -> {
            formatter.format(TimeUnit.MILLISECONDS.toMinutes(timeDiff), RelativeDateTimeFormatter.Direction.AGO, RelativeDateTimeFormatter.Units.MINUTE)
        }
        // 小于1天(今天)
        timeDiff < TimeUnit.DAYS.toMillis(1) -> {
            formatter.format(TimeUnit.MILLISECONDS.toHours(timeDiff), RelativeDateTimeFormatter.Direction.AGO, RelativeDateTimeFormatter.Units.HOUR)
        }
        // 小于2天(昨天)
        timeDiff < TimeUnit.DAYS.toMillis(2) -> {
            formatter.format(1, RelativeDateTimeFormatter.Direction.AGO, RelativeDateTimeFormatter.Units.DAY)
        }
        // 更早的日期
        else -> {
            formatter.format(TimeUnit.MILLISECONDS.toDays(timeDiff), RelativeDateTimeFormatter.Direction.AGO, RelativeDateTimeFormatter.Units.DAY)
        }
    }
}

这个方法的优势是完全不用关心各语言的翻译细节,系统会根据你传入的Locale自动输出对应的“Today”“Yesterday”等文案。

方案2:自定义字符串资源+动态Locale适配

如果需要更定制化的文案(比如不想用系统默认的表述),可以自己维护多语言字符串,然后通过ContextWrapper切换Locale来获取对应翻译。

步骤1:添加多语言字符串

在res/values/strings.xml中定义基础文案:

<string name="today">Today</string>
<string name="yesterday">Yesterday</string>
<string name="days_ago">%d days ago</string>

然后在对应语言的资源文件夹中添加翻译,比如res/values-es/strings.xml(西班牙语):

<string name="today">Hoy</string>
<string name="yesterday">Ayer</string>
<string name="days_ago">Hace %d días</string>

步骤2:编写格式化代码

import android.content.Context
import android.content.ContextWrapper
import android.content.res.Configuration
import java.util.Locale
import java.util.concurrent.TimeUnit

fun formatCustomRelativeTime(context: Context, timestamp: Long, targetLocale: Locale): String {
    // 创建临时Context,切换到目标Locale,避免影响全局配置
    val localeContext = ContextWrapper(context).apply {
        val config = resources.configuration.apply {
            setLocale(targetLocale)
        }
        resources.updateConfiguration(config, resources.displayMetrics)
    }

    val now = System.currentTimeMillis()
    val diffDays = TimeUnit.MILLISECONDS.toDays(now - timestamp)

    return when (diffDays) {
        0L -> localeContext.getString(R.string.today)
        1L -> localeContext.getString(R.string.yesterday)
        else -> localeContext.getString(R.string.days_ago, diffDays)
    }
}
方案3:临时修改Locale适配DateUtils

如果你坚持想用DateUtils.getRelativeDateTimeString,可以通过临时修改当前Context的Locale来实现适配,记得用完后恢复原Locale,避免影响其他功能:

import android.content.Context
import android.content.res.Configuration
import android.text.format.DateUtils
import java.util.Locale

fun getRelativeDateTimeWithLocale(context: Context, timestamp: Long, targetLocale: Locale): String {
    val originalLocale = context.resources.configuration.locale
    try {
        // 临时切换Locale
        val config = context.resources.configuration.apply {
            setLocale(targetLocale)
        }
        context.resources.updateConfiguration(config, context.resources.displayMetrics)

        return DateUtils.getRelativeDateTimeString(
            context,
            timestamp,
            DateUtils.MINUTE_IN_MILLIS,
            DateUtils.WEEK_IN_MILLIS,
            0
        ).toString()
    } finally {
        // 恢复原Locale
        val config = context.resources.configuration.apply {
            setLocale(originalLocale)
        }
        context.resources.updateConfiguration(config, context.resources.displayMetrics)
    }
}

这个方法要注意,修改Configuration可能会触发界面重绘,所以尽量在非UI线程或者临时Context中使用。


内容的提问来源于stack exchange,提问作者Henning Hall

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:09:24