9

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.

Norbert Koch
  • 533
  • 6
  • 17
  • 5
    I had never heard about that one before. Maybe they just included it in the hope that someone would implement a calendar where there are (sometimes) 13 months. Maybe someone did, but the implementation was not included in the standard JRE. – Ole V.V. Jun 23 '17 at 09:02
  • 4
    In case anyone other than me is wondering about the *i* in *Undecimber*: in Latin, 10 is decem with e in both syllables, while 11 is undecim with an i (the names up to December come from a time when March was the first month of the year). See for example http://blogs.transparent.com/latin/latin-numbers-1-100/. – Ole V.V. Jun 23 '17 at 11:02

2 Answers2

7

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.

Community
  • 1
  • 1
  • 1
    I fear that this answer is not directly related to the `UNDECIMBER`-constant itself what was asked for. You should also correct your statement that "there's no implementations that extends java.util.Calendar". There are implementations: GregorianCalendar, BuddhistCalendar and JapaneseImperialCalendar (okay, these 3 calendars have just 12 months). Side note: The Japanese calendar had sometimes 13 months until 1872 (implemented in my library [Time4J](http://time4j.net/javadoc-en/net/time4j/calendar/JapaneseCalendar.html)). – Meno Hochschild Jun 27 '17 at 14:39
  • 1
    @MenoHochschild Well, it's not **directly** talking about `UNDECIMBER`, but my understanding is that the OP also asked about implementations of calendars with 13 months. I also corrected my statement, thanks a lot! –  Jun 27 '17 at 14:42
  • 1
    It might also be interesting that the Coptic calendar implementation you refer to has once been a part of JSR-310 (shipped with [Threeten-project](http://threeten.sourceforge.net/apidocs/javax/time/i18n/CopticChronology.html)) but was obviously not wanted by Oracle (as far as I know only as test class in [TCK-kit](http://www.javatips.net/api/openjdk-master/jdk/test/java/time/tck/java/time/chrono/CopticDate.java)). Therefore there is no localization support at all in the Threeten-Extra-version because Oracle does/did not supply any text resources. – Meno Hochschild Jun 27 '17 at 14:51
  • That explains why I get an empty string for the 13th month if I use the pattern `MMM` –  Jun 27 '17 at 15:10
  • 2
    Indeed, but this gap (no i18n) is true for the whole threeten-extra project. For comparison, see the api-example for my [EthiopicCalendar](http://time4j.net/javadoc-en/net/time4j/calendar/EthiopianCalendar.html) in the language Amharic which will never be realizable in threeten-extra due to some design limitations of `DateTimeFormatter` (watch out the usage of Ethiopian numerals for the year part only). – Meno Hochschild Jun 27 '17 at 15:21
4

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!

anacron
  • 6,443
  • 2
  • 26
  • 31
  • Nevertheless it seems arbitrarily or not completed. – Norbert Koch Jun 23 '17 at 09:53
  • @NorbertKoch Welcome to programming. :) ... but I think it might be used, for instance the Chinese calendar is a lunar one. You can convert between those two and maybe then you need the constant (?): https://stackoverflow.com/questions/28923204/how-convert-gregorian-to-chinese-lunar-calendar – hamena314 Jun 23 '17 at 09:57
  • 1
    Okay, this post clarify, that this constant **supports** the implementation. To me the JavaDoc reads like: "We have this constant, but whatever". Now it is easier to understand. – Norbert Koch Jun 23 '17 at 11:05
  • @NorbertKoch In standard Java, there is indeed no implementation or usage of `UNDECIMBER`. As far as I know, ICU4J uses a very similar [constant](http://icu-project.org/apiref/icu4j/com/ibm/icu/util/Calendar.html#UNDECIMBER) in order to support some calendars with 13 months (chinese, hebrew, coptic, ethiopian), but the ICU4J-classes are defined in another package. – Meno Hochschild Jun 23 '17 at 16:58