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
相关产品推荐
相关产品推荐

