如何在Kotlin/Java中格式化本地化时长?RelativeDateTimeFormatter时态配置问题
在Kotlin/Java中格式化本地化时长的方案
针对你的需求——把Duration转换为无时态的本地化可读字符串(比如“1分30秒”或“1m 30s”),以下是两种实用方案:
一、使用ICU4J的DurationFormatter(推荐,专业本地化支持)
ICU4J提供了专门的DurationFormatter,原生支持本地化时长格式化,能直接输出完整文本或缩写风格的结果,完全满足你的需求。
Java代码示例
import com.ibm.icu.text.DurationFormatter; import com.ibm.icu.util.ULocale; import java.time.Duration; public class DurationFormatDemo { public static void main(String[] args) { Duration targetDuration = Duration.ofMinutes(1).plusSeconds(30); // 中文完整风格 DurationFormatter fullFormatter = DurationFormatter.getInstance( ULocale.CHINESE, DurationFormatter.Style.FULL ); System.out.println(fullFormatter.format(targetDuration)); // 输出:1分30秒 // 英文缩写风格 DurationFormatter shortFormatter = DurationFormatter.getInstance( ULocale.ENGLISH, DurationFormatter.Style.SHORT ); System.out.println(shortFormatter.format(targetDuration)); // 输出:1m 30s } }
Kotlin代码示例
import com.ibm.icu.text.DurationFormatter import com.ibm.icu.util.ULocale import java.time.Duration fun main() { val targetDuration = Duration.ofMinutes(1).plusSeconds(30) val fullFormatter = DurationFormatter.getInstance(ULocale.CHINESE, DurationFormatter.Style.FULL) println(fullFormatter.format(targetDuration)) // 1分30秒 val shortFormatter = DurationFormatter.getInstance(ULocale.ENGLISH, DurationFormatter.Style.SHORT) println(shortFormatter.format(targetDuration)) // 1m 30s }
需要引入ICU4J依赖(以Maven为例):
<dependency> <groupId>com.ibm.icu</groupId> <artifactId>icu4j</artifactId> <version>74.1</version> <!-- 使用最新稳定版本 --> </dependency>
二、手动拆分Duration+本地化资源(无额外依赖)
如果不想引入第三方库,可以自己拆分Duration的时、分、秒字段,结合ResourceBundle加载本地化字符串拼接结果。
Java代码示例
import java.time.Duration; import java.util.ResourceBundle; public class ManualDurationFormatter { public static String formatLocalizedDuration(Duration duration, String localeTag) { ResourceBundle bundle = ResourceBundle.getBundle("DurationMessages", java.util.Locale.forLanguageTag(localeTag)); long totalSeconds = duration.getSeconds(); long hours = totalSeconds / 3600; long remainingSeconds = totalSeconds % 3600; long minutes = remainingSeconds / 60; long seconds = remainingSeconds % 60; StringBuilder result = new StringBuilder(); if (hours > 0) { result.append(hours).append(" ").append(bundle.getString("hour")).append(" "); } if (minutes > 0) { result.append(minutes).append(" ").append(bundle.getString("minute")).append(" "); } if (seconds > 0 || result.isEmpty()) { result.append(seconds).append(" ").append(bundle.getString("second")); } return result.toString().trim(); } public static void main(String[] args) { Duration duration = Duration.ofMinutes(1).plusSeconds(30); System.out.println(formatLocalizedDuration(duration, "zh-CN")); // 1 分钟 30 秒 System.out.println(formatLocalizedDuration(duration, "en-US")); // 1 minute 30 seconds } }
本地化资源文件
创建DurationMessages_zh_CN.properties:
hour=小时 minute=分钟 second=秒
创建DurationMessages_en_US.properties:
hour=hour minute=minute second=second
关于RelativeDateTimeFormatter的说明
你提到的RelativeDateTimeFormatter确实无法配置为输出无时态的纯时长——它的设计目标是生成相对于某个时间点的时态化表述(如“1分钟前”“1分钟后”),没有提供输出纯时长的选项,因此不适合你的场景。
内容的提问来源于stack exchange,提问作者frodo2975
相关产品推荐
相关产品推荐

