6

I'm having this little piece of code:

import java.text.SimpleDateFormat;
import java.util.Date;

public class Main {

    public static void main(String[] args) {

        SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz");

        System.out.println(format.format(new Date()));

    }
}

With Java 8, the output is:

Tue, 16 Jul 2019 13:16:54 AEST

With Java 11:

Tue., 16 Jul. 2019 13:16:54 AEST

Why is there a difference and how should I modify my code to make it work evenly in both Java versions?

I was actually using Handlebars while finding this issue, and I could narrow it down to the Java version - but it would be cool to know how to use Handlebars to produce the same result for the same format string...)

Siaynoq
  • 452
  • 1
  • 5
  • 13
  • 2
    I recommend you don’t use `SimpleDateFormat` and `Date`. Those classes are poorly designed and long outdated, the former in particular notoriously troublesome. Instead use `DateTimeFormatter` and for example `ZonedDateTime`, both from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Jul 16 '19 at 03:42
  • 1
    Which is your default locale? Also asking because I don’t think I’ve met a locale where the dot (period) after English language abbreviations (Tue and Jul) would be correct. – Ole V.V. Jul 16 '19 at 03:43
  • 2
    Possible duplicate of [JDK dateformatter parsing DayOfWeek in German locale, java8 vs java9](https://stackoverflow.com/questions/46244724/jdk-dateformatter-parsing-dayofweek-in-german-locale-java8-vs-java9) and/or [Parsing time with LocalTime](https://stackoverflow.com/questions/56814020/parsing-time-with-localtime). In short, it’s because of CLDR. – Ole V.V. Jul 16 '19 at 03:45
  • My locale is `en_AU` – Siaynoq Jul 16 '19 at 03:46
  • 1
    The locale used in the latter link, https://stackoverflow.com/questions/56814020/parsing-time-with-localtime, is en-AU too. You will want to read through the comments, also when they are a bit long. – Ole V.V. Jul 16 '19 at 03:48

1 Answers1

24

TL;DR

Run your Java 9 and later (including Java 11) with the system property java.locale.providers defined like this:

java -Djava.locale.providers=COMPAT,CLDR YourApp

Now output is without the dots, in the same format as on Java 8, for example:

Tue, 16 Jul 2019 14:24:15 AEST

CLDR

Java gets its locale data, including abbreviations used for days of the week and for months in different languages, from up to four sources. Up to Java 8 Java’s own locale data were the default. From Java 8 locale data from Unicode Common Locale Data Repository (CLDR; see links at the bottom) are included too, and from Java 9 they are the default. Java’s own data are still included and accessible by specifying COMPAT in the above system property. We need to put it first in the string as the sources are tried in turn.

One might have expected that another (and perhaps even a nicer) solution would be to use CLDR in all Java versions. Curiously this doesn’t give us the same format on all Java versions in this case. Here is the output when setting the property to CLDR,JRE (JRE is the old name for COMPAT, on Java 8 we need to use this instead).

On Java 8:

Tue, 16 Jul 2019 14:35:02 AEST

On Java 9 and 11:

Tue., 16 Jul. 2019 14:35:52 AEST

CLDR comes in versions, and not the same version is included with the different Java versions.

java.time

Here’s the snippet I have used for the above outputs.

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(
            "EEE, dd MMM yyyy HH:mm:ss zzz", Locale.forLanguageTag("en-AU"));
    ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Australia/Sydney"));
    System.out.println(now.format(formatter));

I am using and recommending java.time, the modern Java date and time API. The date-time classes that you used, SimpleDateFormat and Date, are long outdated and were always poorly designed, so I recommend avoiding them. On Java 8 and later there’s certainly no reason why we should use them, and java.time has been backported to Java 6 and 7 too.

Links

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
  • 2
    Thank you very much for your exhaustive explanation - I appreaciate the time you put into the answer. This is the reason I visit (and post to) stackoverflow! +1 for your funny headings (tl;dr / cldr) :D – Siaynoq Jul 16 '19 at 11:47