Joda-Time 的构建器方法的替代方案是基于模式的解决方案。这是由我的图书馆 Time4J 提供的。使用 Duration.Formatter 类的示例(添加了一些空格以提高可读性 - 删除空格将产生所需的 C# 样式):
IsoUnit unit = ClockUnit.MILLIS;
Duration<IsoUnit> dur = // normalized duration with multiple components
Duration.of(123456, unit).with(Duration.STD_PERIOD);
Duration.Formatter<IsoUnit> f = // create formatter/parser with optional millis
Duration.Formatter.ofPattern("D'd' h'h' m'm' s[.fff]'s'");
System.out.println(f.format(dur)); // output: 0d 0h 2m 3.456s
此格式化程序还可以打印java.time-API 的持续时间(但是,该类型的规范化功能不太强大):
System.out.println(f.format(java.time.Duration.ofMillis(123456))); // output: 0d 0h 2m 3.456s
OP 期望“123456 ms 作为 long 将被打印为 4d1h3m5s”以明显错误的方式计算。我认为草率是原因。上面定义的相同持续时间格式化程序也可以用作解析器。以下代码显示“4d1h3m5s”对应于349385000 = 1000 * (4 * 86400 + 1 * 3600 + 3 * 60 + 5):
System.out.println(
f.parse("4d 1h 3m 5s")
.toClockPeriodWithDaysAs24Hours()
.with(unit.only())
.getPartialAmount(unit)); // 349385000
另一种方法是使用 net.time4j.PrettyTime 类(这也适用于本地化输出和打印“昨天”、“下周日”、“4 天前”等相关时间):
String s = PrettyTime.of(Locale.ENGLISH).print(dur, TextWidth.NARROW);
System.out.println(s); // output: 2m 3s 456ms
s = PrettyTime.of(Locale.ENGLISH).print(dur, TextWidth.WIDE);
System.out.println(s); // output: 2 minutes, 3 seconds, and 456 milliseconds
s = PrettyTime.of(Locale.UK).print(dur, TextWidth.WIDE);
System.out.println(s); // output: 2 minutes, 3 seconds and 456 milliseconds
文本宽度控制是否使用缩写。也可以通过选择适当的语言环境来控制列表格式。例如,标准英语使用 Oxform 逗号,而 UK 不使用。 Time4J 的最新版本 v5.5 支持 90 多种语言,并使用基于 CLDR 存储库(行业标准)的翻译。