带有 Joda-Time DateTimeFormatter 的属格(波兰语区域设置)中的月份名称
我有哪个包含日期2012-12-28,我想用本地化的月份名称(即波兰语中的12月)打印它,这在波兰语中与主格不同(分别为grudnia和grudzień)。因为我也想使用我自己创建的自定义格式(AFAIK在Joda-Time中是正确的方法):LocalDate
DateTimeFormatter
DateTimeFormatterBuilder
private static final DateTimeFormatter CUSTOM_DATE_FORMATTER
= new DateTimeFormatterBuilder()
.appendLiteral("z dnia ")
.appendDayOfMonth(1)
.appendLiteral(' ')
.appendText(new MonthNameGenitive()) // <--
.appendLiteral(' ')
.appendYear(4, 4)
.appendLiteral(" r.")
.toFormatter()
.withLocale(new Locale("pl", "PL")); // not used in this case apparently
输出应为“z dnia 28 grudnia 2012 r.”。
我的问题是关于用箭头标记的行:我应该如何实现?目前它扩展并有相当多的代码:MonthNameGenitive
DateTimeFieldType
final class MonthNameGenitive extends DateTimeFieldType {
private static final long serialVersionUID = 1L;
MonthNameGenitive() {
super("monthNameGenitive");
}
@Override
public DurationFieldType getDurationType() {
return DurationFieldType.months();
}
@Override
public DurationFieldType getRangeDurationType() {
return DurationFieldType.years();
}
@Override
public DateTimeField getField(final Chronology chronology) {
return new MonthNameGenDateTimeField(chronology.monthOfYear());
}
private static final class MonthNameGenDateTimeField
extends DelegatedDateTimeField {
private static final long serialVersionUID = 1L;
private static final ImmutableList<String> MONTH_NAMES =
ImmutableList.of(
"stycznia", "lutego", "marca", "kwietnia", "maja", "czerwca",
"lipca", "sierpnia", "września", "października", "listopada",
"grudnia");
private MonthNameGenDateTimeField(final DateTimeField field) {
super(field);
}
@Override
public String getAsText(final ReadablePartial partial,
final Locale locale) {
return MONTH_NAMES.get(
partial.get(this.getType()) - 1); // months are 1-based
}
}
}
对我来说似乎很草率,不是防弹的,因为我必须实现许多神奇的方法,而且我只使用并覆盖了一种方法(),而还有其他具有相同名称的方法:DelegatedDateTimeField
getAsText(ReadablePartial, Locale)
getAsText(long, Locale)
getAsText(long)
getAsText(ReadablePartial, int, Locale)
getAsText(int, Locale)
有没有更好的方法来获得所需的输出(使用)或我的方法正确但非常冗长?DateTimeFormatter
编辑:
我试图用新的JDK8 Time API(类似于Joda,基于JSR-310)实现同样的事情,它可以很容易地完成:
private static final java.time.format.DateTimeFormatter JDK8_DATE_FORMATTER
= new java.time.format.DateTimeFormatterBuilder()
.appendLiteral("z dnia ")
.appendValue(ChronoField.DAY_OF_MONTH, 1, 2, SignStyle.NORMAL)
.appendLiteral(' ')
.appendText(ChronoField.MONTH_OF_YEAR, MONTH_NAMES_GENITIVE) // <--
.appendLiteral(' ')
.appendValue(ChronoField.YEAR, 4)
.appendLiteral(" r.")
.toFormatter()
.withLocale(new Locale("pl", "PL"));
其中带有自定义月份名称,因此非常易于使用。请参阅 DateTimeFormatterBuilder#appendText(TemporalField, Map)。
MONTH_NAMES_GENITIVE
Map<Long, String>
有趣的是,在JDK8中,这整个波兰月份名称的玩法是不必要的,因为DateFormatSymbols.getInstance(new Locale(“pl”, “PL”)).getMonths()
默认以genitive格式返回月份名称...虽然这个变化对于我的用例是正确的(在波兰语中,我们使用属名中的月份名称说“今天是2012年12月28日”),但在其他一些情况下可能会很棘手(我们使用主格说“这是2012年12月”),并且它是向后不兼容的。