在Android上,如何使用本地化的时间单位将持续时间格式化为字符串?

在Android上,如何使用本地化的时间单位将持续时间格式化为字符串?,android,time,formatting,Android,Time,Formatting,我想将时间长度(例如,以秒为单位)格式化为一个字符串,该字符串将包含时间单位的本地化名称。例如,对于输入8692,我将得到字符串“2小时24分钟52秒”,每个语言的时间单位都正确本地化。安卓系统中有什么类可以做到这一点吗?有人知道这方面的外部开源库吗?谢谢。我不知道任何开源库,但是如果我正确理解了这个问题,那么手工操作应该不会太难: public static String foo(int duration) { int hours = duration/3600; int mi

我想将时间长度(例如,以秒为单位)格式化为一个字符串,该字符串将包含时间单位的本地化名称。例如,对于输入8692,我将得到字符串“2小时24分钟52秒”,每个语言的时间单位都正确本地化。安卓系统中有什么类可以做到这一点吗?有人知道这方面的外部开源库吗?谢谢。

我不知道任何开源库,但是如果我正确理解了这个问题,那么手工操作应该不会太难:

public static String foo(int duration) {
    int hours = duration/3600;
    int minutes = (duration%3600)/60;
    int seconds = duration%60;
    return hours + getResources().getString(R.string.hours) +
           minutes + getResources().getString(R.string.minutes) +
           seconds + getResources().getString(R.string.seconds);
}
然后在
strings.xml
中定义这些字符串,并像通常一样对其进行本地化。(见附件)

对于Android,有
Duration
class(),您可以使用它,但是它的
toString()
方法并不能完全满足您的需要

编辑只是为了完整性:我现在更了解您的问题,您不想手动定位所有时间单位。Unicode公共语言环境数据存储库提供了一些(嗯,很多)有趣的数据。它们提供几乎所有您可能想要本地化的内容的XML数据,例如
de.XML
(德语):


震惊
{0}眩晕
{0}Stunden
{0}pro Stunde
我认为这是过分的,但正如我所说:为了完整性。

我就是这样做的

val minuteString = systemResources.getString(systemResources.getIdentifier("minute", "string", "android"))
val secondString = systemResources.getString(systemResources.getIdentifier("second", "string", "android"))
val hourString = systemResources.getString(systemResources.getIdentifier("hour", "string", "android"))
val dayString = systemResources.getString(systemResources.getIdentifier("day", "string", "android")

在这个文件中,您可以查找其他时间单位资源

我在尝试打印带有本地化格式的Kotlin
持续时间
类型时遇到了同样的问题,因为我找不到好的解决方案,所以我自己写了一个。它基于Android 9中开始提供的API(用于本地化单元),但对于较低的Android版本,它可以回退到英语单元,因此可以与较低的目标应用程序一起使用

下面是它在使用方面的外观(请参阅Kotlin type以了解第1行):

val duration=5天加3小时加2分钟加214毫秒
DurationFormat().格式(持续时间)/“5天3小时2分钟”
持续时间格式(Locale.GERMANY)。格式(持续时间)/“5T 3Std.2Min。”
DurationFormat(Locale.forLanguageTag(“ar”).format(duration)/“duration”
DurationFormat().format(duration,smallestUnit=DurationFormat.Unit.HOUR)/“5天3小时”
DurationFormat().格式(15分钟)/“15分钟”
DurationFormat().格式(0.hours)/“0秒”
如您所见,您可以为
DurationFormat
类型指定自定义
locale
。默认情况下,它使用
locale.getDefault()
。还支持数字符号与罗马语符号不同的语言(通过
NumberFormat
)。此外,您可以指定自定义的
smallestUnit
,默认情况下它设置为
SECOND
,因此不会显示毫秒。请注意,任何值为
0
的单位都将被忽略,如果整数为
0
,则最小的单位将与值
0
一起使用

这是完整
持续时间格式
类型
,请随意复制(也可作为包括单元测试在内的组件提供):

导入android.icu.text.MeasureFormat
导入android.icu.text.NumberFormat
导入android.icu.util.MeasureUnit
导入android.os.Build
导入java.util.Locale
导入kotlin.time.Duration
导入kotlin.time.ExperimentalTime
导入kotlin.time.days
导入kotlin.time.hours
导入kotlin.time.ms
导入kotlin.time.minutes
导入kotlin.time.seconds
@实验时间
数据类DurationFormat(val locale:locale=locale.getDefault()){
枚举类单元{
天、小时、分钟、秒、毫秒
}
乐趣格式(持续时间:kotlin.time.duration,最小单位:Unit=Unit.SECOND):字符串{
var formattedStringComponents=mutableListOf()
var剩余=持续时间
for(单位为unit.values()){
val组件=计算组件(单位,余数)
余数=时间(单位){
Unit.DAY->余数-component.days
Unit.HOUR->余数-component.hours
Unit.MINUTE->余数-component.minutes
单位秒->余数-分量秒
单位毫秒->余数-分量毫秒
}
val unitDisplayName=unitDisplayName(单位)
如果(组件>0){
val formattedComponent=NumberFormat.getInstance(区域设置)。format(组件)
formattedStringComponents.add(“$formattedComponent$unitDisplayName”)
}
如果(单位==最小单位){
val formattedZero=NumberFormat.getInstance(区域设置).format(0)
if(formattedStringComponents.isEmpty())formattedStringComponents.add(“$formattedZero$unitDisplayName”)
打破
}
}
返回格式化的StringComponents.joinToString(“”)
}
private fun calculateComponent(单位:单位,余数:持续时间)=时间(单位){
Unit.DAY->余数.inDays.toLong()
Unit.HOUR->restinutes.inhour.toLong()
Unit.MINUTE->restinutes.inMinutes.toLong()
Unit.SECOND->rements.unseconds.toLong()
Unit.millis秒->余数.inmillises.toLong()
}
private fun unitDisplayName(unit:unit)=if(Build.VERSION.SDK\u INT>=Build.VERSION\u code.P){
val measureFormat=measureFormat.getInstance(区域设置,measureFormat.FormatWidth.窄)
时间(单位){
DurationFormat.Unit.DAY->measureFormat.getUnitDisplayName(MeasureUnit.DAY)
DurationFormat.Unit.HOUR->measureFormat.getUnitDisplayName(MeasureUnit.HOUR)
DurationFormat.Unit.MINUTE->measureFormat.getUnitDisplayName(MeasureUnit.MINUTE)
DurationFormat.Unit.SECOND->measureFormat.getUnitDisplayName(MeasureUnit.SECOND)
DurationFormat.Unit.millised->measureFormat.getUnitDisplayName(MeasureUnit.MILLIS
val minuteString = systemResources.getString(systemResources.getIdentifier("minute", "string", "android"))
val secondString = systemResources.getString(systemResources.getIdentifier("second", "string", "android"))
val hourString = systemResources.getString(systemResources.getIdentifier("hour", "string", "android"))
val dayString = systemResources.getString(systemResources.getIdentifier("day", "string", "android")