Polishing

master
Sam Brannen 1 year ago
parent
commit
4431caf92b
  1. 12
      Date-and-Time-Formatting-with-JDK-20-and-higher.md

12
Date-and-Time-Formatting-with-JDK-20-and-higher.md

@ -14,27 +14,27 @@ JDK 20 adopted Unicode [CLDR 42](https://cldr.unicode.org/downloads/cldr-42) whi @@ -14,27 +14,27 @@ JDK 20 adopted Unicode [CLDR 42](https://cldr.unicode.org/downloads/cldr-42) whi
**Consequently, applications that rely on date/time parsing and formatting may encounter incompatible changes in behavior when running on JDK 20 or higher – for example, web applications that make use of Spring Framework's `@DateTimeFormat` support.**
On JDK 20, 21, and 22, applications can use the `-Djava.locale.providers=COMPAT` command-line argument for the `java` compiler in order to force the use of legacy locale data which uses a standard space for the space character that precedes the `period` in formatted date/time text.
On JDK 20, 21, and 22, applications can use the `-Djava.locale.providers=COMPAT` command-line argument for the `java` executable in order to force the use of legacy locale data which uses a standard space for the space character that precedes the `period` in formatted date/time text.
Note, however, that the aforementioned `COMPAT` mode has been removed in JDK 23.
**It is also worth pointing out that string represenations of date/time formats can no longer be reliably encoded with ISO-8859-1 (latin-1) encoding.** The reason is that characters such as a narrow non-breaking space (`"\u202F"`) can only be properly represented with UTF encoding. For example, if you have a web application that generates HTML web pages using ISO-8859-1 encoding and containing time values formatted using the US English locale (for example, `3:30 PM`), the formatted times will contain a `?` instead of a narrow non-breaking space before AM or PM (such as `3:30?PM`).
**It is also worth pointing out that string represenations of date/time formats can no longer be reliably encoded with ISO-8859-1 (latin-1) encoding.** The reason is that characters such as a narrow non-breaking space (`"\u202F"`) can only be properly represented with UTF encoding. For example, if you have a web application that generates HTML web pages using ISO-8859-1 encoding and containing time values formatted using the US English locale (for example, `3:30 PM`), the formatted times will contain a `?` instead of a narrow non-breaking space before AM or PM (such as `3:30?PM`) beginning with JDK 20.
**In summary, developers and frameworks must find a way to either avoid or deal with locale-sensitive date/time formats provided by both current and future versions of the Unicode CLDR.**
## Recommendations
The Spring team recommends the use of ISO standardized formats for both parsing and formatting of date/time values whenever possible. For example, consider using a predefined `iso` pattern in Spring's `@DateTimeFormat` annotation (such as `ISO.DATE_TIME`) or one of the `ISO_*` constants defined in `java.time.format.DateTimeFormatter` (such as `ISO_DATE_TIME`) for programmatic handling of JSR-310 `java.time` value types.
The Spring team recommends the use of ISO standardized formats for both parsing and formatting of date/time values whenever possible. For example, consider using a predefined `iso` pattern in Spring's `@DateTimeFormat` annotation (for example, `@DateTimeFormat(iso = ISO.DATE_TIME)`) or one of the `ISO_*` constants defined in `java.time.format.DateTimeFormatter` (such as `ISO_DATE_TIME`) for programmatic handling of JSR-310 `java.time` value types.
Another option is to always use date/time formatting patterns that you control. In other words, instead of relying on predefined locale-sensitive patterns such as `@DateTimeFormat(style = "-M")` or `java.time.format.FormatStyle.MEDIUM` to parse or format a time, define your own date/time pattern that parses and formats times the way you expect – for example, `"HH:mm a"` to handle US English times such as `3:30 PM`.
Another option is to always use date/time formatting patterns that you control. In other words, instead of relying on predefined locale-sensitive patterns such as `@DateTimeFormat(style = "-M")` or `java.time.format.FormatStyle.MEDIUM` to parse or format a time, define your own date/time pattern that parses and formats times the way you expect – for example, `"HH:mm a"` to handle US English times such as `3:30 PM`, with a standard space before the `a` and `PM`.
**Using an ISO standardized format or a concrete pattern that you control allows for reliable system-independent and locale-independent parsing and formatting of date/time values.** However, if that is not an option for your use case, consider one of the _lenient_ approaches outlined below.
The Spring team also recommends the use of UTF encoding whenever possible – for example, `UTF-8`.
**The Spring team also recommends the use of UTF encoding whenever possible – for example, `UTF-8`.**
## Options for Application Code and Tests
Within application code or tests you may need to match against an input string to determine if the provided text adheres to the format you expect; however, the input string may contain a narrow non-breaking space where you have traditionally expected a standard space. To address use cases like that, you can use the `\p{Zs}` regular expression pattern to match against any Unicode space character. For example, `12:00\\p{Zs}PM` matches against `"12:00<SPACE>PM"` and `"12:00<NNBSP>PM"`, where `<SPACE>` is a standard space and `<NNBSP>` is a narrow non-breaking space (`"\u202F"`).
Within application code or tests you may need to match against an input string to determine if the provided text adheres to the format you expect; however, beginning with JDK 20 the input string may contain a narrow non-breaking space where you have traditionally expected a standard space. To address use cases like that, you can use the `\p{Zs}` regular expression pattern to match against any Unicode space character. For example, `12:00\\p{Zs}PM` matches against `"12:00<SPACE>PM"` and `"12:00<NNBSP>PM"`, where `<SPACE>` is a standard space and `<NNBSP>` is a narrow non-breaking space (`"\u202F"`).
If you are using JUnit Jupiter as your testing framework and wish to run certain tests on JDK versions before or after the CLDR changes in the JDK, you can annotate a test class or test method as follows.

Loading…
Cancel
Save