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

Regression : SimpleDateFormat incorrectly parses dates formatted with Z and z pattern letters

    XMLWordPrintable

Details

    • b32
    • Verified

    Description

      SYNOPSIS
      --------
      Regression: SimpleDateFormat incorrectly parses dates formatted with Z and z pattern letters

      OPERATING SYSTEM
      ----------------
      All

      FULL JDK VERSION
      ----------------
      All JDKs containing fix for CR 7130335
      e.g. 6u32 onwards, 7u4 onwards, JDK 8

      DESCRIPTION
      -----------
      Consider the following process:

      1. Create a Date object
      2. Format that Date object with a custom SimpleDateFormat
      3. Parse the String created by step 2 with the same SimpleDateFormat
         object

      The end result should normally be a Date object with exactly the same time as one created in step 1, because the same format is used for formatting and parsing.

      However, since the fix for CR 7130335 this is not always the case. It seems that format Strings containing both the Z and z pattern letters are interpreted incorrectly by the parse() method when daylight savings time is active. The attached testcase demonstrates this.

      REPRODUCTION INSTRUCTIONS
      -------------------------
      1. Compile and run the attached testcase

      Expected behaviour (6u31 and earlier)
      -------------------------------------
      C:\>java DateTimeTest
       date.toString(): Wed Aug 08 13:32:28 BST 2012 (getTime() = 1344429148569)
         Format string: EEE, d MMM yyyy HH:mm:ss.SSS Z (z)
      After formatting: Wed, 8 Aug 2012 13:32:28.569 +0100 (BST)
         After parsing: Wed Aug 08 13:32:28 BST 2012 (getTime() = 1344429148569)

      Note that the Dates before and after parsing are the same.

      Observed behaviour (6u32 and later)
      -----------------------------------
      C:\>java DateTimeTest
       date.toString(): Wed Aug 08 13:32:28 BST 2012 (getTime() = 1344429148569)
         Format string: EEE, d MMM yyyy HH:mm:ss.SSS Z (z)
      After formatting: Wed, 8 Aug 2012 13:32:28.569 +0100 (BST)
         After parsing: Wed Aug 08 12:32:28 BST 2012 (getTime() = 1344425548569)

      Note that the Dates before and after parsing are different by one hour.

      The testcase is hard coded to test Europe/London (BST), but the problem seems to occur under any DST timezone, for example:

      C:\>java DateTimeTest
       date.toString(): Wed Aug 08 08:32:28 EDT 2012 (getTime() = 1344429148569)
         Format string: EEE, d MMM yyyy HH:mm:ss.SSS Z (z)
      After formatting: Wed, 8 Aug 2012 08:32:28.569 -0400 (EDT)
         After parsing: Wed Aug 08 07:32:28 EDT 2012 (getTime() = 1344425548569)

      C:\>java DateTimeTest
       date.toString(): Wed Aug 08 15:32:28 EEST 2012 (getTime() = 1344429148569)
         Format string: EEE, d MMM yyyy HH:mm:ss.SSS Z (z)
      After formatting: Wed, 8 Aug 2012 15:32:28.569 +0300 (EEST)
         After parsing: Wed Aug 08 14:32:28 EEST 2012 (getTime() = 1344425548569)

      Also, the problem only happens when the Z and z pattern letters are bot present in the format string. If we remove either of these pattern letters the problem does not occur:

      C:\>java DateTimeTest
       date.toString(): Wed Aug 08 13:32:28 BST 2012 (getTime() = 1344429148569)
         Format string: EEE, d MMM yyyy HH:mm:ss.SSS Z ()
      After formatting: Wed, 8 Aug 2012 13:32:28.569 +0100 ()
         After parsing: Wed Aug 08 13:32:28 BST 2012 (getTime() = 1344429148569)

      C:\>java DateTimeTest
       date.toString(): Wed Aug 08 13:32:28 BST 2012 (getTime() = 1344429148569)
         Format string: EEE, d MMM yyyy HH:mm:ss.SSS (z)
      After formatting: Wed, 8 Aug 2012 13:32:28.569 (BST)
         After parsing: Wed Aug 08 13:32:28 BST 2012 (getTime() = 1344429148569)

      SUGGESTED FIX
      -------------
      Our only suggestion at this time is to back out the fix for 7130335.

      TESTCASE SOURCE
      ---------------
      import java.text.*;
      import java.util.*;
      import java.io.*;

      public class DateTimeTest {
          public static void main(String args[]) throws Exception {
              TimeZone.setDefault(TimeZone.getTimeZone("Europe/London"));

              long aDstTime = 1344429148569L; // An arbitrary date in mid August 2012

              final String formatString = "EEE, d MMM yyyy HH:mm:ss.SSS Z (z)";
             
              final Date dateBeforeParsing = new Date(aDstTime);
              System.out.println(" date.toString(): " + dateBeforeParsing + " (getTime() = " + dateBeforeParsing.getTime() + ")");

              final SimpleDateFormat outFormat = new SimpleDateFormat(formatString, Locale.US);
              System.out.println(" Format string: " + formatString);

              final String formattedDateString = outFormat.format(dateBeforeParsing);
              System.out.println("After formatting: " + formattedDateString);

              final Date dateAfterParsing = outFormat.parse(formattedDateString);
              System.out.println(" After parsing: " + dateAfterParsing + " (getTime() = " + dateAfterParsing.getTime() + ")");
          }
      }

      Attachments

        Issue Links

          Activity

            People

              coffeys Sean Coffey
              dkorbel David Korbel (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: