Yet another post in my series of poking about in the odd corners of Java to see what interesting or confusing snippets of info I can find. This time I’m poking at a new feature from Java 8 - the Chronology API.

This is an attempt to put a clean interface on the idea of different parts of the world using different calendars. I’m not sure, but it appears the intent is to replace the Calendar and GregorianCalendar classes from java.util, much like the java.time facilities are a new implementation of temporal stuff to replace the much-hated java.util.Date and its friends.

I’ll admit I haven’t ever had to wrestle with either different Calendar types or Chronology types. All the work I’ve done has stuck firmly with the common western ISO calendar - and that has quite enough scope for confusion!

Unlike the i18n features I’ve talked about in earlier similar posts, all the Chronology info has remained the same across Java 8, 9 and 10. This shouldn’t be surprising but it’s a relief anyway!

The code used as the source of this article is here but basically it’s:

get a unicode capable output stream
get a sorted list of all the available Chronologies
print a bunch of info about each Chronology
 * its "code"
 * its current date
 * a list of eras
print the count of known Chronologies

Java 10 and JShell FTW!

An aside I just had to mention - although the Java 8 code linked above is what I originally used, it’s great to see how easy it is to do similar kinds of scribbles in JShell. The code above, done in a Java 10 JShell looks roughly like this…

import java.time.chrono.Chronology;
String chronStr = "Id: %s, current date: %s\n";
Chronology.getAvailableChronologies().forEach(c -> {
    System.out.printf(chronStr, c.getId(), c.dateNow().toString());
    c.eras().forEach(System.out::println);
});

That’s less than 10 lines of code rather than more than 30, and a whole lot less of the edit-compile-run cycle. Which makes me very happy.

Anyway, back to the results - I compiled with OpenJDK’s Java 8 version, then ran it in OpenJDK’s JVMs for Java 8, 9 and 10. I took the outputs and diffed them to see what changed between Java versions. The answer was … nothing. The results were the same:

Id: Hijrah-umalqura, current date: Hijrah-umalqura AH 1439-09-24
    Era: AH
Id: ISO, current date: 2018-06-08
    Era: BCE
    Era: CE
Id: Japanese, current date: Japanese Heisei 30-06-08
    Era: Meiji
    Era: Taisho
    Era: Showa
    Era: Heisei
Id: Minguo, current date: Minguo ROC 107-06-08
    Era: BEFORE_ROC
    Era: ROC
Id: ThaiBuddhist, current date: ThaiBuddhist BE 2561-06-08
    Era: BEFORE_BE
    Era: BE
Count: 5

What does that mean?

Basically this is a way of abstracting the common constructs used in different the ways used to count the days and years as they pass, and the epoch milestones they use between their eras.

To be honest, almost everything I’ve done so far with dates and times has ignored every type of Chronology except ISO, and even more specifically I’ve been able to start with the Unix epoch and an integer of some size related to how far from Unix epoch the datetime is. Then all the fun has been converting that integer into a displayable date or doing datetime calculations.

But if you’re dealing with dates a long time ago, with people using different calendars, you may need to read the Chronology docs and the other time.chrono docs really carefully and do your own scribbles.

Just out of interest, I had a quick look at where those Chronology types are used and how they’re constructed. It’s clear that apart from the Hijrah the other 4 are basically the Gregorian calendar with different epoch years. Other than that they’re specifically defined to be identical (same month counts, leap year calcs, etc).

So we don’t have any ready made Chronology instances for the really interesting calendars, like some of the complex Asian ones, the Jewish and other religious ones, or anything else you might find while wandering around Wikipedia

This may be wrong, but I get the impression that the 4 non-ISO variants are mainly intended as demonstrators of the Chronology facility. It may be that their intent is to show how a Chronology can be constructed with various rule complexities - then expect developers to construct their own Chronology implementations and bolt them into the runtime using the relevant interfaces.

Anyway, a quick summary of those 4 non-ISO Chronologies …

Hijrah-umalqura

The Hijrah calendar is used in the Islamic world, based on lunar cycles and has variants due to some people using actual lunar sightings and others using calculated lunar positions. This specific variant apparently follows the rules used by the Saudi Arabian calendar.

From the docs, it appears if you need a different variant, you’ll actually need to set up a specific new Chronology variant for the precise rules you’re following.

Japanese

It looks like the day, month, year lengths in this follow the Gregorian calendar, the only difference is the epoch year, so the year number is always different to the ISO year number, but everything appears to tick forwards at the same rate.

However, they do have multiple eras. It seems these are based around the reign of Japanese emperors, and count forwards from the emperor’s accession date. So we are currently in year “Heisei 30” era as emperor Akihito started in 1989 (ISO). When a new emperor arrives, we’ll get a new era and start counting from 1 again.

If you’re dealing with dates before the Meiji era, all bets are off, get a big whiteboard, a lot of history books, and some strong coffee!

Minguo

This is a Chinese calendar used in Taiwan, although apparently not the formal calendar of China (which officially uses the Gregorian, ISO calendar). And definitely not the famously complex traditional Chinese farming one.

Note that the eras are based around “ROC” - formation of the Republic of China, using 1912 (ISO) as their epoch. It appears the actual calendars used were variable until 1949, so there will be edge cases around these calendars still in living memory.

As with the Japanese Chronology, anything in the BEFORE_ROC era, or earlier (?), is firmly in the realms of serious history books and strong coffee.

ThaiBuddhist

This is similar to the Japanese Chronology - basically the same as a Gregorian calendar, but with a different epoch date (add 543). This isn’t one of the more complex Buddhist calendars, but it is apparently the one most commonly used in Thailand.