我创建了一个实现java.time.temporal.TemporalField
的CENTURY
字段 -这个问题并不关注该字段的正确实现细节(稍后会处理),我对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的一个有用的增强。