Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8277049

ZonedDateTime parse in Fall DST transition fails to retain the correct zonename.

    XMLWordPrintable

Details

    • b27
    • generic
    • generic

    Description

      ADDITIONAL SYSTEM INFORMATION :
      Reproduced on OpenJDK Java 1.8.0_292 (Linux), 11.0.11(Linux) and 17.0.1 (Linux&Mac)

      A DESCRIPTION OF THE PROBLEM :
      Using the ZonedDateTime the parsing of a datetime String that does not include an offset (so no +01:00) but does include the 'z' = "daylight savings aware zone name" then parsing in the DST transition in the Fall fails to produce the correct result.

      Assume this DateTimeFormatter that does not use an offset but does have the name of the timezone 'z'.
      DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS z");

      This 'z' is defined on https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/format/DateTimeFormatter.html as "If the pattern letter is 'z' the output is the daylight savings aware zone name."

      So when formatting a time using this format under ZondeId "Europe/Amsterdam" you get either "CET" or "CEST".

      The problem is that when parsing a String in this format with this specification the distinction between "CET" and "CEST" is lost.

      Normally a round trip over "parse" and "format" results in the original input again.

      I found this fails in the hour when the clock moves back to transition from summertime to wintertime.


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS z");
      System.out.println(fmt.format(ZonedDateTime.parse("2021-10-31 02:30:00.000 CET", fmt)));
      System.out.println(fmt.format(ZonedDateTime.parse("2021-10-31 02:30:00.000 CEST", fmt)));


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      2021-10-31 02:30:00.000 CET
      2021-10-31 02:30:00.000 CEST
      ACTUAL -
      2021-10-31 02:30:00.000 CEST
      2021-10-31 02:30:00.000 CEST


      ---------- BEGIN SOURCE ----------
      App.java:

      import java.time.ZonedDateTime;
      import java.time.format.DateTimeFormatter;

      public class App {
          public static void main(String[] args) {
              expectSame("2021-10-31 02:30:00.000 CET");
              expectSame("2021-10-31 02:30:00.000 CEST");
              expectSame("2021-11-07 01:30:00.000 EDT");
              expectSame("2021-11-07 01:30:00.000 EST");
          }

          public static void expectSame(String datetimeString) {
              DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS z");
              String roundTrip = fmt.format(ZonedDateTime.parse(datetimeString, fmt));
              System.out.println(
                      datetimeString + " | " +
                              roundTrip +
                              (datetimeString.equals(roundTrip) ? "" : " <--- BAD")
              );
          }
      }

      Then just do:
              $ javac App.java && java App
              2021-10-31 02:30:00.000 CET | 2021-10-31 02:30:00.000 CEST <--- BAD
              2021-10-31 02:30:00.000 CEST | 2021-10-31 02:30:00.000 CEST
              2021-11-07 01:30:00.000 EDT | 2021-11-07 01:30:00.000 EDT
              2021-11-07 01:30:00.000 EST | 2021-11-07 01:30:00.000 EDT <--- BAD

      ---------- END SOURCE ----------

      FREQUENCY : always


      Attachments

        Issue Links

          Activity

            People

              naoto Naoto Sato
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              6 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: