What does Calendar.UNDECIMBER do?

2019-04-29 07:44发布

问题:

There is a constant in the Calendar class called: UNDECIMBER. It describes the 13th month.

Is there a useful purpose for this constant? In Wikipedia it is written that it is for the lunar calendar. But there is no implementation for such calendar.

And does there exist any solutions for the 14th month (Duodecimber)?

I didn't found so much in the web, and I would like to find out more about this topic.

回答1:

As already said, some lunar (and other ancient) calendars have 13 months. One example is the Coptic Calendar.

Although there are no implementations of calendars with 13 months that extends java.util.Calendar, in Java 8's new API there are some. With the introduction of the new java.time API, it was also created the ThreeTen Extra project, which contains an implementation for that.

The class is org.threeten.extra.chrono.CopticChronology, which extends the native java.time.chrono.Chronology. I've just made a sample code to create a date in this calendar and loop through its months:

// Coptic calendar
CopticChronology cal = CopticChronology.INSTANCE;
// range for month of year (from 1 to 13)
System.out.println("month range: " + cal.range(ChronoField.MONTH_OF_YEAR)); // 1 - 13

// getting a date in Coptic calendar and loop through the months
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("dd/MM/yyyy");
// September 11th is equivalent to 01/01 in Coptic calendar
CopticDate d = cal.date(LocalDate.of(2017, 9, 11));
for (int i = 0; i < 14; i++) {
    System.out.println(fmt.format(d));
    d = d.plus(1, ChronoUnit.MONTHS);
}

The output is:

month range: 1 - 13
01/01/1734
01/02/1734
01/03/1734
01/04/1734
01/05/1734
01/06/1734
01/07/1734
01/08/1734
01/09/1734
01/10/1734
01/11/1734
01/12/1734
01/13/1734
01/01/1735

Note that the year changed just after the 13th month.


The ThreeTen Extra project also has an implementation for the Ethiopian calendar, which has 13 months as well.


And, as an example of a calendar with 14 months, there's the PaxChronology class, which implements the Pax Calendar: a proposed reform calendar system, but not currently in use, as far as I know.

Quoting wikipedia:

The common year is divided into 13 months of 28 days each, whose names are the same as in the Gregorian calendar, except that a month called Columbus occurs between November and December. The first day of every week, month and year would be Sunday.

In leap years, a one-week month called Pax would be inserted after Columbus.

And according to javadoc:

Leap years occur in every year whose last two digits are divisible by 6, are 99, or are 00 and the year is not divisible by 400.

Example:

PaxChronology paxCal = PaxChronology.INSTANCE;
System.out.println("month range: " + paxCal.range(ChronoField.MONTH_OF_YEAR));

PaxDate pd = paxCal.date(1930, 1, 1);
for (int i = 0; i < 15; i++) {
    // fmt is the same DateTimeFormatter from previous example
    System.out.println(fmt.format(pd));
    // adjusting for first day of next month - using TemporalAdjuster because
    // adding 1 ChronoUnit.MONTHS throws an exception for 14th month (not sure why)
    pd = pd.plus(30, ChronoUnit.DAYS).with(TemporalAdjusters.firstDayOfMonth());
}

Output:

month range: 1 - 13/14
01/01/1930
01/02/1930
01/03/1930
01/04/1930
01/05/1930
01/06/1930
01/07/1930
01/08/1930
01/09/1930
01/10/1930
01/11/1930
01/12/1930
01/13/1930
01/14/1930
01/01/1931

You can notice that the year changes after the 14th month. The range is 1 - 13/14 because years can have 13 or 14 months, depending if it's a leap year or not.



回答2:

The Calendar.UNDECIMBER is an additional constant in the Calendar class that is not typically used in the widely used Gregorian Calendar but certain Lunar calendars use a 13th month. That's the purpose of this field.

Refer to the Java Docs below:

https://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html#UNDECIMBER

Wikipedia article for this:

https://en.wikipedia.org/wiki/Undecimber

There is also a mention of a 14th month - Duodecimber in the wiki. Unfortunately, Java does not (yet) support that.


Hope this helps!