java – SimpleDateFormat with German locale

I’m not saying it’s a pleasant solution, but it seems to be a solution.

    Map dayOfWeekTexts = Map.of(1L, "Mo", 2L, "Di", 
            3L, "Mi", 4L, "Do", 5L, "Fr", 6L, "Sa", 7L, "So");
    Map monthTexts = Map.ofEntries(Map.entry(1L, "Jan"), 
            Map.entry(2L, "Feb"), Map.entry(3L, "Mär"), Map.entry(4L, "Apr"),
            Map.entry(5L, "Mai"), Map.entry(6L, "Jun"), Map.entry(7L, "Jul"),
            Map.entry(8L, "Aug"), Map.entry(9L, "Sep"), Map.entry(10L, "Okt"),
            Map.entry(11L, "Nov"), Map.entry(12L, "Dez"));

    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .appendText(ChronoField.DAY_OF_WEEK, dayOfWeekTexts)
            .appendLiteral(' ')
            .appendText(ChronoField.MONTH_OF_YEAR, monthTexts)
            .appendPattern(" dd HH:mm:ss z Z yyyy")

    String toParse = "Mo Aug 18 11:25:26 MESZ +0200 2014";
    OffsetDateTime odt = OffsetDateTime.parse(toParse, formatter);
    ZonedDateTime zdt = ZonedDateTime.parse(toParse, formatter);

Exit running on my Oracle JDK 10.0.1:


Furthermore, no Nice solution could exist.

Java.timeThe modern Java API of date and time allows us to specify the texts to be used for fields for both formatting and parsing. Then I exploit it for both the day of the week and the month, specifying the dot-less abbreviations used with the old COMPAT or JRE local data. I used Java 9 Map.of And Map.ofEntries to create the maps we need. If this works in Java 8, you need to find another way to populate the two maps, I trust you will.

If you need an old one Java.util.Date (Probably in a legacy code base), convert like this:

    Date date = Date.from(odt.toInstant());
    System.out.println("As legacy Date: " + date);

Exit in my time zone (Europe / Copenhagen, probably roughly agrees with yours):

As legacy Date: Mon Aug 18 11:25:26 CEST 2014

Tip for a strategy

I’m thinking if it had been me, I would have considered proceeding like this:

  1. Wait . Set the relevant system property from Java: System.setProperty("Java.locale.providers", "COMPAT,CLDR"); so that it is not forgotten in any environment. The COMPAT locale data has been around since 1.0 (I think, at least close), so a lot of code out there depends on it (not just yours). The name was changed from JRE to COMPAT in Java 9. To me this may seem like a plan to keep the data for some time yet. According to the early access documentation it will still be available in Java 11 (the next Java “long term support”) and without deprecation notice or the like. And should Java be removed in the future, you’ll likely be able to find out soon enough that you can address the issue before upgrading.
  2. Use my solution above .
  3. Use the interface of the local service provider to which Basil Bourque linked. There is no doubt that this is the nice solution in case COMPAT data needs to be removed at an unknown time in the future. You may also be able to copy the COMPAT locale data into your files so they can’t take it away from you, just check for copyright issues before doing so. The reason I mentioned the last nice solution is that you said you’re not happy with having to set a system property in every possible environment where your program might run. As far as I know, using your local data via the local service provider interface will still require you to set the same system property (only to a different value).

Leave a comment