使用埃塞俄比亚年表格式化乔达时间不显示月份名称

Formatting Joda time with Ethiopic Chronology not displaying the name of the month

我正在使用 Joda 时间将格里高利历日期和时间转换为埃塞俄比亚纪年法,我正在尝试将其格式化为 "MMMM dd, yyyy" 格式。我希望日期显示为 "Meskerem 01, 2007" 而不是我得到“1 01, 2007”。这是 Joda 时间的错误还是我做错了什么?

DateTimeFormatter dtf = DateTimeFormat.forPattern("MMMM dd, yyyy")
Date time myDate = new DateTime(2014,9,11,0,0,0,0).withChronology(EthiopicChronology.getInstance()).toString(dtf)

看看下面的例子:

@Grab(group='joda-time', module='joda-time', version='2.7') 
import org.joda.time.format.DateTimeFormat
import org.joda.time.format.DateTimeFormatter
import org.joda.time.DateTime
import org.joda.time.chrono.EthiopicChronology

DateTimeFormatter dtf = DateTimeFormat.forPattern("MMMM dd, yyyy")
println new DateTime(2014,9,11,0,0,0,0).toString(dtf)

它能正确打印日期 - 完整的月份名称。现在看看 docs。它声明 Chronology 对象 returns 一个 new 格式化程序。可能这不是错误,但使用了刚刚返回的格式化程序而不是定义的格式化程序。

更新

这可能是一个错误,它也不适用于 BuddhistChronology

@Grab(group='joda-time', module='joda-time', version='2.7') 
import org.joda.time.format.DateTimeFormat
import org.joda.time.format.DateTimeFormatter
import org.joda.time.DateTime
import org.joda.time.chrono.*

DateTimeFormatter dtf = DateTimeFormat.forPattern("MMMM dd, yyyy")
println new DateTime(2014,9,11,0,0,0,0).withChronology(BuddhistChronology.getInstance()).toString(dtf)

嗯,JodaTime在国际化方面一直做的不好,不好意思。但我会提出一个解决方法。

DateTimePrinter printer =
        new DateTimePrinter() {

    @Override
    public int estimatePrintedLength() {
        return 8; // type the maximum chars you need for printing ethiopic months
    }

    @Override
    public void printTo(StringBuffer buf, ReadablePartial partial, Locale locale) {
        int index = LocalDate.now().indexOf(DateTimeFieldType.monthOfYear());
        int month = partial.getValue(index);
        print(buf, month);
    }

    @Override
    public void printTo(Writer out, ReadablePartial partial, Locale locale)
        throws IOException
    {
        StringBuffer sb = new StringBuffer();
        printTo(sb, partial, locale);
        out.write(sb.toString());
    }

    @Override
    public void printTo(
        StringBuffer buf,
        long         instant,
        Chronology   chrono,
        int          displayOffset,
        DateTimeZone displayZone,
        Locale       locale
    ) {
        LocalDate date = new LocalDate(instant, EthiopicChronology.getInstance());
        print(buf, date.getMonthOfYear());
    }

    @Override
    public void printTo(
        Writer       out,
        long         instant,
        Chronology   chrono,
        int          displayOffset,
        DateTimeZone displayZone,
        Locale       locale
    ) throws IOException
    {
        StringBuffer sb = new StringBuffer();
        printTo(sb, instant, chrono, displayOffset, displayZone, locale);
        out.write(sb.toString());
    }

    private void print(StringBuffer buf, int month) {
        switch (month) {
            case 1 : // attention: ethiopic month index
                buf.append("Meskerem");
                break;
            // case 2: etc.
            default :
                buf.append(month);
        }
    }
};

DateTimeFormatter dtf =
    new DateTimeFormatterBuilder().append(printer).appendPattern(" dd, yyyy").toFormatter();
Chronology chronology = EthiopicChronology.getInstance();
DateTime ethiopic = new DateTime(2014, 9, 11, 0, 0, 0).withChronology(chronology);
String myDate = ethiopic.toString(dtf);
System.out.println(ethiopic); // 2007-01-01T00:00:00.000+02:00 (ethiopic month number and year and day-of-month!!!)
System.out.println(myDate); // Meskerem 01, 2007

请注意:此代码(如@Opal 所建议?)对我不起作用:

Chronology chronology = EthiopicChronology.getInstance();
DateTimeFormatter dtf =
    DateTimeFormat.forPattern("MMMM dd, yyyy").withChronology(chronology);
String myDate = new DateTime(2014, 9, 11, 0, 0, 0).toString(dtf2);
System.out.println(myDate); // 1 01, 2007

原因是令人遗憾的是 Joda-Time 不管理自己的非公历年表的文本资源,也比较这个 SO-post。您还可以使用 post 中建议的专用字段实现。在这里,我提出了一个使用 DateTimePrinter 的解决方案,您必须在其中添加所需的缺失月份名称。