Java中的时间间隔本地化

Java中的时间间隔本地化,java,time,localization,jodatime,intervals,Java,Time,Localization,Jodatime,Intervals,我需要将时间间隔表示为如下本地化字符串:10小时25分钟1秒,具体取决于Locale。 用英语手工很容易实现: String hourStr=hours==1?“小时”:“小时”等 但根据不同语言的规则,我需要一些“开箱即用”的Java(可能是Java8)机制。 Java有它吗?或者我需要自己为应用程序中使用的每个语言环境实现它吗?看看。版本2.5支持英语、丹麦语、荷兰语、法语、德语、日语、波兰语、葡萄牙语和西班牙语 Period period = new Period(new LocalDat

我需要将时间间隔表示为如下本地化字符串:
10小时25分钟1秒
,具体取决于
Locale
。 用英语手工很容易实现:
String hourStr=hours==1?“小时”:“小时”

但根据不同语言的规则,我需要一些“开箱即用”的Java(可能是Java8)机制。 Java有它吗?或者我需要自己为应用程序中使用的每个语言环境实现它吗?

看看。版本2.5支持英语、丹麦语、荷兰语、法语、德语、日语、波兰语、葡萄牙语和西班牙语

Period period = new Period(new LocalDate(2013, 4, 11), LocalDate.now());
PeriodFormatter formatter = PeriodFormat.wordBased(Locale.GERMANY);
System.out.println(formatter.print(period)); // output: 1 Jahr, 2 Monate und 3 Wochen

formatter = formatter.withLocale(Locale.ENGLISH);
System.out.println(formatter.print(period)); // output: 1 Jahr, 2 Monate und 3 Wochen (bug???)

formatter = PeriodFormat.wordBased(Locale.ENGLISH);
System.out.println(formatter.print(period)); // output: 1 year, 2 months and 3 weeks
但是,您可能需要调整交互时间字符。为此,您可能需要复制和编辑类路径中具有以下格式的消息资源文件(此处为英文变体):

从版本2.5开始,也可以应用复杂的正则表达式来模拟更复杂的复数规则。就我个人而言,我认为它对用户不友好,正则表达式对于阿拉伯语等语言可能不够(我的第一印象)。本地化还有其他限制,请参见此

旁注:Java8绝对不能进行本地化的持续时间格式化

从2015年8月26日起更新: 使用my library Time4J-v4.3版本(可在Maven Central中获得),以下更强大的解决方案是可能的,它支持当前45种语言:

import static net.time4j.CalendarUnit.*;
import static net.time4j.ClockUnit.*;

// the input for creating the duration (in Joda-Time called Period)
IsoUnit[] units = {YEARS, MONTHS, DAYS, HOURS, MINUTES, SECONDS};
PlainTimestamp start = PlainDate.of(2013, 4, 11).atTime(13, 45, 21);
PlainTimestamp end = SystemClock.inLocalView().now();

// create the duration
Duration<?> duration = Duration.in(units).between(start, end);

// print the duration (here not abbreviated, but with full unit names)
String s = PrettyTime.of(Locale.US).print(duration, TextWidth.WIDE);

System.out.println(s);
// example output: 1 year, 5 months, 7 days, 3 hours, 25 minutes, and 49 seconds
导入静态net.time4j.CalendarUnit.*;
导入静态net.time4j.ClockUnit.*;
//用于创建持续时间的输入(以称为Period的Joda时间为单位)
IsoUnit[]单位={年、月、日、时、分、秒};
PlainTimestamp start=PlainDate.of(2013,4,11).atTime(13,45,21);
PlainTimestamp end=SystemClock.inLocalView().now();
//创建持续时间
持续时间=持续时间.in(单位).between(开始、结束);
//打印持续时间(此处不缩写,但使用完整的单位名称)
字符串s=PrettyTime.of(Locale.US).print(duration,TextWidth.WIDE);
系统输出打印项次;
//输出示例:1年5个月7天3小时25分钟49秒
为什么Time4J更适合解决您的问题?

  • 它有一种更具表现力的方式来说明应该以哪些单位来计算持续时间
  • 它支持45种语言
  • 它支持有时复杂的语言复数规则,包括从右到左的脚本(如阿拉伯语),无需手动配置
  • 它支持依赖于区域设置的列表模式(使用逗号、空格或“and”等词)
  • 它支持3种不同的文本宽度:宽、缩写(短)和窄
  • 与Java-8的互操作性更好,因为像
    Java.time.Period
    Java.time.Duration
    这样的Java-8类型被Time4J理解

AFAIK Java不支持这种开箱即用的格式。也许乔达时间图书馆有这个功能。等待Jon Skeet来启发我们……java时间和joda时间都没有这种能力,我认为没有现成的方法可以做到这一点。使用这两种工具,您可以使用DateTimeFormatterBuilder创建自己的DateTimeFormatter。@谢谢,但这篇文章有点过时(现在Time4J支持86种语言)。
import static net.time4j.CalendarUnit.*;
import static net.time4j.ClockUnit.*;

// the input for creating the duration (in Joda-Time called Period)
IsoUnit[] units = {YEARS, MONTHS, DAYS, HOURS, MINUTES, SECONDS};
PlainTimestamp start = PlainDate.of(2013, 4, 11).atTime(13, 45, 21);
PlainTimestamp end = SystemClock.inLocalView().now();

// create the duration
Duration<?> duration = Duration.in(units).between(start, end);

// print the duration (here not abbreviated, but with full unit names)
String s = PrettyTime.of(Locale.US).print(duration, TextWidth.WIDE);

System.out.println(s);
// example output: 1 year, 5 months, 7 days, 3 hours, 25 minutes, and 49 seconds