JDK-8000529 : Regression : SimpleDateFormat incorrectly parses dates formatted with Z and z pattern letters
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.text
  • Affected Version: 6u31-rev,6u32,7u4,8
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2012-10-08
  • Updated: 2014-01-09
  • Resolved: 2013-04-25
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6 JDK 7 JDK 8
6u37Fixed 7u40Fixed 8 b89Fixed
Related Reports
Relates :  
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() + ")");
    }                                                                    
} 
Comments
Verified 8 b122 win7
09-01-2014