1 changed files with 76 additions and 2 deletions
@ -1,3 +1,77 @@
@@ -1,3 +1,77 @@
|
||||
This is a placeholder for forthcoming documentation regarding and date and time parsing and formatting issues with JDK 20+ |
||||
## Overview |
||||
|
||||
See https://github.com/spring-projects/spring-framework/issues/33151 |
||||
This Wiki page discusses date/time formatting and parsing issues that developers may encounter when running their applications on JDK 20+. |
||||
|
||||
Specifically, this document provides background information on changes in the JDK as well as guidance on how to address formatting and parsing issues encountered in Spring applications. |
||||
|
||||
Before you read any further, we highly recommend that you first read [JEP 252: Use CLDR Locale Data by Default](https://openjdk.org/jeps/252). |
||||
|
||||
Although this document primarily focuses on issues related to time formats for the US English locale (for example, `3:30 PM`), numerous other use cases may potentially be affected by locale-sensitive date/time formats provided by the [Unicode Common Locale Data Repository (CLDR) project](https://cldr.unicode.org/). |
||||
|
||||
## Background |
||||
|
||||
JDK 20 adopted Unicode [CLDR 42](https://cldr.unicode.org/downloads/cldr-42) which includes [CLDR-14032](https://unicode-org.atlassian.net/browse/CLDR-14032) that changed the space character that precedes the `period` (AM or PM) in formatted date/time text from a standard space (`" "`) to a narrow non-breaking space (NNBSP: `"\u202F"`). Consequently, applications that rely on date/time parsing and formatting may encounter incompatible changes in behavior when using Spring 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. |
||||
|
||||
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. |
||||
|
||||
Consequently, 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. |
||||
|
||||
If using an ISO standardized format 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`. |
||||
|
||||
### Lenient `@DateTimeFormat` Configuration |
||||
|
||||
TODO |
||||
|
||||
### Lenient Parsing in Tests and Application Code |
||||
|
||||
TODO |
||||
|
||||
### Lenient `SimpleDateFormat` and `DateTimeFormatter` Configuration |
||||
|
||||
In JDK 23, the Java team introduced support for lenient parsing of space characters in `SimpleDateFormat` as well as `DateTimeFormatter`. |
||||
|
||||
`SimpleDateFormat` is lenient by default; however, `DateTimeFormatter` instances are not lenient by default, and factory methods like `DateTimeFormatter.ofLocalizedTime(...)` do not create lenient formatters. |
||||
|
||||
To create a lenient `DateTimeFormatter`, one must forgo the use of the static factory methods in `DateTimeFormatter` and instead make use of the `DateTimeFormatterBuilder`. The following example shows how to create a static factory method for a lenient `DateTimeFormatter` that is comparable to what `DateTimeFormatter.ofLocalizedDateTime(FormatStyle, FormatStyle)` produces. |
||||
|
||||
```java |
||||
pubic static DateTimeFormatter createLenientDateTimeFormatter( |
||||
FormatStyle dateStyle, FormatStyle timeStyle) { |
||||
|
||||
return new DateTimeFormatterBuilder() |
||||
.parseLenient() |
||||
.appendLocalized(dateStyle, timeStyle) |
||||
.toFormatter() |
||||
.withChronology(IsoChronology.INSTANCE); |
||||
} |
||||
``` |
||||
|
||||
## Resources |
||||
|
||||
- https://openjdk.org/jeps/252 |
||||
- https://jdk.java.net/20/release-notes#JDK-8284840 |
||||
- https://cldr.unicode.org/downloads/cldr-42 |
||||
- https://unicode-org.atlassian.net/browse/CLDR-14032 |
||||
- https://bugs.openjdk.org/browse/JDK-8223587 |
||||
- https://bugs.openjdk.org/browse/JDK-8284840 |
||||
- https://bugs.openjdk.org/browse/JDK-8297316 |
||||
- https://bugs.openjdk.org/browse/JDK-8304925 |
||||
- https://bugs.openjdk.org/browse/JDK-8324665 |
||||
|
||||
## Related Spring Issues |
||||
|
||||
- https://github.com/spring-projects/spring-framework/issues/30185 |
||||
- https://github.com/spring-projects/spring-framework/issues/33144 |
||||
- https://github.com/spring-projects/spring-framework/issues/30649 |
||||
- https://github.com/spring-projects/spring-framework/issues/33151 |
||||
- https://github.com/spring-projects/spring-boot/issues/42430 |
||||
|
||||
Loading…
Reference in new issue