2

I currently am migrating a piece of software from Java 11 to Java 17 and noticed that DateTimeFormatter has changed its behaviour when formatting time that contains the AM/PM marker. Earlier, that marker would have been localised (e.g. vorm. for AM in German) and now, it stays AM. This is not a locale-specific issue, because I already have tried this with other locales. The pattern that is being tried here is HH:mm:ss a, where a is the place holder of the marker. How can the previous behaviour be restored?

The DateTimeFormatter is being called using the ofPattern method as follows: ofPattern("HH:mm:ss a", Locale.GERMANY).format(now). The variable now is a LocalDateTime object.

Sae1962
  • 1,122
  • 15
  • 31
domkol
  • 23
  • 4
  • Are you sure that worked with java 11 without a custom formater? I don't think so. You have probably used a `DateTimeFormatterBuilder` and appended a custom `ChronoField.AMPM_OF_DAY` to it. I would be surprised if it worked since it is not usual to format dates having `vorm.` and `nachm.` as a subtitute for `am/pm`. Besides `HH` is for 24 hour format; it should be `hh:mm ....` – Eritrean Mar 24 '22 at 15:28
  • https://stackoverflow.com/questions/44411475/how-to-change-am-pm-symbol-to-my-own-alphabet-when-using-java-8-date-time-api – Eritrean Mar 24 '22 at 15:43
  • @Eritrean Yes, I'm sure that it worked under Java 11 without any custom formatter because the code has not been changed and it really is as mentioned in the question. No, the code is not using `DateTimeFormatterBuilder` but I have now looked into that method `ofPattern` and that is using the builder: `return new DateTimeFormatterBuilder().appendPattern(pattern).toFormatter(locale);` I agree that localised substitutes are rare but it's a requirement. You're right about the pattern but I didn't define mine. – domkol Mar 24 '22 at 16:51
  • Just in case of someone asking: Replacing the pattern `HH:mm:ss a` to `hh:mm:ss a` did not change the output in this case. – domkol Mar 24 '22 at 16:54
  • It’s probably the locale data bundled with Java 17 being different, not the formatter class itself. – Ole V.V. Mar 25 '22 at 19:26
  • I can only partially reproduce your observations in my Java 17. While for locales `Locale.GERMAN` and `Locale.GERMANY` I do get `PM`, for many other locales I do not. Including locales of language codes he, lv, yi, cs, el, af, sa, fa, lb and no. – Ole V.V. Mar 25 '22 at 19:37
  • It seems the locale data is the same - for example https://github.com/openjdk/jdk11/blob/master/src/jdk.localedata/share/classes/sun/text/resources/ext/JavaTimeSupplementary_de.java#L84 vs https://github.com/openjdk/jdk17/blob/master/src/jdk.localedata/share/classes/sun/text/resources/ext/JavaTimeSupplementary_de.java#L84 is both nachm. for German – Klara Nov 23 '22 at 13:23

1 Answers1

0

Creating proper datetime format with correct Chronology and Locale will give am/pm in desired locale. For Germany and Chinese, I was able to get correct data, but for Hindi and Italy it’s not giving expected output. May be this is how data is showed in their respective region.

final String pattern = DateTimeFormatterBuilder.getLocalizedDateTimePattern(FormatStyle.FULL, FormatStyle.FULL, Chronology.ofLocale(Locale.GERMAN),Locale.GERMAN);
final DateTimeFormatter targetFormat = DateTimeFormatter.ofPattern(pattern).withLocale(Locale.GERMAN);
final String value = ZonedDateTime.now().format(targetFormat);
Sae1962
  • 1,122
  • 15
  • 31