JDK-8257647 : "UTC" time zone inconsistently parsed with "DateTimeFormatter" after Java11
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.time
  • Affected Version: 11,15,16
  • Priority: P4
  • Status: Closed
  • Resolution: Not an Issue
  • OS: generic
  • CPU: generic
  • Submitted: 2020-11-30
  • Updated: 2021-03-10
  • Resolved: 2020-12-03
Related Reports
Relates :  
Description
ADDITIONAL SYSTEM INFORMATION :
Windows Server 2019, macOS 10.15, Ubuntu 18.04.
Java 11, Java 15.

A DESCRIPTION OF THE PROBLEM :
The `UTC` time zone specified in a String with date and time is parsed to a different `ZoneId` in Java11+ rather than in Java8.

Consider the following pattern `MM/dd/yyyy hh:mm a z` used to create a `DateTimeFormatter` with the US locale.

When a date string such as e.g. `05/17/2021 09:23 PM UTC` is parsed to a `ZonedDateTime` using the formatter, the `ZoneId` value of the `ZonedDateTime` is different when different JDK versions are used.

For JDK 8-10 and 12-14 the value of the `ZoneId` is `UTC`. But for JDK 11 and JDK 15 the value is equal to `Etc/UTC`.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
The easiest way to reproduce the issue is to clone the repository https://github.com/yuri-sergiichuk/jdk-zone-parsing-inconsistency and run Gradle build `./gradlew build`.

1. Create `DateTimeFormatter` with the `MM/dd/yyyy hh:mm a z` pattern:

    ```
    DateTimeFormatter ZONED_FORMATTER = DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm a z", Locale.US);
    ```

2. Parse date-time string `05/17/2021 09:23 PM UTC` to a `ZonedDateTime` object:

    ```
    ZonedDateTime result = ZONED_FORMATTER.parse(dateString, ZonedDateTime::from);
    ```

3. Check `ZoneId` value of the result:

    ```
    result.getZone().equals(ZoneId.of("UTC"))
    ```


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The parsed `ZonedDateTime` zone is equal to `ZoneId.of("UTC")`.
ACTUAL -
The parsed `ZonedDateTime` zone is equal to `ZoneId.of("Etc/UTC")`.

---------- BEGIN SOURCE ----------
final class ZonedParser {

    public static void main(String[] args) {
        DateTimeFormatter ZONED_FORMATTER = DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm a z", Locale.US);
        ZonedDateTime result = ZONED_FORMATTER.parse("05/17/2021 09:23 PM UTC", ZonedDateTime::from);
        if (!result.getZone().equals(ZoneId.of("UTC"))) {
            throw new IllegalStateException("Zone ID must be equal to `UTC`.");
        }
    }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Use `Etc/UTC` time zone in date string in Java 11 and Java 15 and just `UTC` in others.

FREQUENCY : always



Comments
According to CLDR, time zone ids, "Etc/UTC" and "UTC" are aliases: https://github.com/openjdk/jdk/blob/f83fd4acb4c04285d14eae6b8fee0de58bfcdd45/make/data/cldr/common/bcp47/timezone.xml#L435 And "Etc/UTC" is the canonical id for those equivalents (as it is the first id in the "alias" attribute). In JDK15, the change was made to make the canonical tzid as the parsed time zone with the fix to JDK-8234347 (and it is backported to 11u), thus you see this behavior on these releases.
03-12-2020

The observations on Windows 10: JDK 8: Passed, ZoneID is UTC JDK 11: Failed, ZoneID is Etc/UTC not UTC JDK 13: Passed JDK 15: Failed JDK 16: Failed
03-12-2020