在日期时间格式化程序中添加自定义本地化文本,用于新的自定义时态字段



我创建了一个实现java.time.temporal.TemporalFieldCENTURY字段 -这个问题并不关注该字段的正确实现细节(稍后会处理),我对DateTimeFormatter问题感兴趣,如下所述。

基本上,该字段获取时态对象的ChronoField.YEAR并使用此值来计算世纪(考虑到 1世纪是从 1 年到 100 年,计算是用getFrom(TemporalAccessor temporal)方法进行的 - 但正如我所说,我们不要在这些细节上坚持太多)。

最基本的用法是:

LocalDate.of(2017, 1, 1).get(CENTURY); // 21

在这种情况下,它返回21

该字段也可用于DateTimeFormatter

DateTimeFormatter fmt = new DateTimeFormatterBuilder()
.appendPattern("dd/MM/yyyy ")
.appendValue(CENTURY)
.toFormatter();
System.out.println(fmt.format(LocalDate.of(2017, 1, 1))); // 01/01/2017 21

上述内容的输出为:

2017-01-01 21


但我想做的是为此字段使用自定义本地化文本。如果我创建这样的格式化程序:

DateTimeFormatter fmt = new DateTimeFormatterBuilder()
.appendPattern("dd/MM/yyyy ")
// century text
.appendText(CENTURY, TextStyle.SHORT)
// use English locale
.toFormatter(Locale.ENGLISH);
System.out.println(fmt.format(LocalDate.of(2017, 1, 1))); // 01/01/2017 21

由于我的新CENTURY字段没有本地化数据,因此文本只是其自身的值21

我正在尝试找到一种为此字段添加自定义本地化字符串的方法,例如,它对月份和星期几所做的那样(假设我已经设置了资源包属性文件)。

检查源代码,我发现格式化程序内部使用TextPrinterParser,而又使用DateTimeTextProvider来获取本地化的字符串,但这些类都不是公共的,不能使用也不能扩展。而且 API 似乎没有提供为新字段添加自定义本地化字符串的方法。

我只能通过使用反射和java.lang.reflect.Proxy来覆盖TextPrinterParser的行为来做到这一点,但我想知道是否有更好的方法(不需要所有这些"魔法")。

如何做到这一点(如果可能)?


我知道我也可以使用appendText(TemporalField field, Map<Long,String> textLookup),但这不会是"区域设置敏感"的解决方案(尽管它似乎是可用的最佳解决方法)。

这在今天的java.time.*是不可能的。DateTimeTextProvider类旨在扩展,但在开发过程中被取消了作用域。提供可插拔的文本提供程序将是Java的一个有用的增强。

最新更新