JDK-6433699 : SimpleDateFormat formats 'z' as GMT, 'Z' as +0100
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.text
  • Affected Version: 5.0
  • Priority: P5
  • Status: Closed
  • Resolution: Duplicate
  • OS: linux
  • CPU: x86
  • Submitted: 2006-06-05
  • Updated: 2011-02-16
  • Resolved: 2006-06-05
Related Reports
Duplicate :  
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
*** Listed in the same order as the operating systems above

[thib@sul-lockss30 temp]$ java -version
java version "1.5.0_05"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_05-b05)
Java HotSpot(TM) Client VM (build 1.5.0_05-b05, mixed mode, sharing)

C:\Documents and Settings\Thib>java -version
java version "1.5.0_06"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-b05)
Java HotSpot(TM) Client VM (build 1.5.0_06-b05, mixed mode)

$ java -version
java version "1.5.0_06"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-112)
Java HotSpot(TM) Client VM (build 1.5.0_06-64, mixed mode, sharing)

Linux sul-lockss30.stanford.edu 2.6.15-1.1833_FC4 #1 Wed Mar 1 23:41:37 EST 2006 i686 athlon i386 GNU/Linux

C:\Documents and Settings\Thib>ver
Microsoft Windows XP [Version 5.1.2600]

$ uname -va
Darwin <machine> 8.6.1 Darwin Kernel Version 8.6.1: Tue Mar  7 16:55:45 PST 2006; root:xnu-792.9.22.obj~1/RELEASE_I386 i386 i386

thib@aeolus$ uname -va
FreeBSD aeolus 6.0-RELEASE FreeBSD 6.0-RELEASE #0: Thu Nov  3 09:36:13 UTC 2005     ###@###.###:/usr/obj/usr/src/sys/GENERIC  i386
thib@aeolus$ java -version
java version "1.5.0-p2"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-p2-root_20_jan_2006_18_01)
Java HotSpot(TM) Client VM (build 1.5.0-p2-root_20_jan_2006_18_01, mixed mode)

# /usr/local/jre-1.4.2/bin/java -version
java version "1.4.2-p7"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2-p7-_27_apr_2006_10_52)
Java HotSpot(TM) Client VM (build 1.4.2-p7-_27_apr_2006_10_52, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
[thib@sul-lockss30 temp]$ uname -va

# uname -va
OpenBSD netblock-66-159-222-203.dslextreme.com 3.9 LOCKSS#230 i386


EXTRA RELEVANT SYSTEM CONFIGURATION :
Most or all of the machines above are in California and are set up to be in the Pacific time zone in a United States locale.

A DESCRIPTION OF THE PROBLEM :
When the default time zone is set to various versions of a GMT offset of 1 allowed by the little grammar in the Javadoc, SimpleDateFormatter formats dates into some format that denotes a GMT+1 time zone (in some way), and if the resulting string is parsed by the same instance, the resulting date is the same as the original.

But when the time zone is set to "Europe/London", the format parameter 'Z' results in "+0100", but the format parameter 'z' results in "GMT". This is counter-intuitive at best. The result is that a date formatted with a 'z' format parameter and parsed by the same instance ends up being projected an hour into the future, but a date formatted with the 'Z' format parameter and parsed by the same instance comes back the same as the original.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the program below. For each one of the time zone strings in main(), the time zone is set, then the date 0 is created and two SimpleDateFormat objects are instantiated, one with "yyyy-MM-dd HH:mm:ss.S z" and one with "yyyy-MM-dd HH:mm:ss.S Z". The date is formatted by the first formatter (and the result shown), then immediately parsed back into a date (and the date shown). The same is performed on the second formatter. Finally, the roundtrip results of both formatters are compared for equality.


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The result of re-parsing a formatted date should be the original date, namely 0, regardless of the formatter used. Thus additionally the comparison of the roundtrip results of both formatter should declare them equal.
ACTUAL -
All behave as expected except "Europe/London" with "yyyy-MM-dd HH:mm:ss.S z". Date(0) is formatted as "GMT", which causes the re-parsed date to be 3600000.

Timezone: GMT+1
1970-01-01 01:00:00.0 GMT+01:00
0
1970-01-01 01:00:00.0 +0100
0
true

Timezone: GMT+01
1970-01-01 01:00:00.0 GMT+01:00
0
1970-01-01 01:00:00.0 +0100
0
true

Timezone: GMT+100
1970-01-01 01:00:00.0 GMT+01:00
0
1970-01-01 01:00:00.0 +0100
0
true

Timezone: GMT+0100
1970-01-01 01:00:00.0 GMT+01:00
0
1970-01-01 01:00:00.0 +0100
0
true

Timezone: GMT+1:00
1970-01-01 01:00:00.0 GMT+01:00
0
1970-01-01 01:00:00.0 +0100
0
true

Timezone: GMT+01:00
1970-01-01 01:00:00.0 GMT+01:00
0
1970-01-01 01:00:00.0 +0100
0
true

Timezone: Europe/London
1970-01-01 01:00:00.0 GMT
3600000
1970-01-01 01:00:00.0 +0100
0
false



REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.text.*;
import java.util.*;

public class DateFormatterTest {

    protected static void tryOneTimeZone(String timeZone) throws Exception {
        TimeZone.setDefault(TimeZone.getTimeZone(timeZone));
        System.out.println("Timezone: " + timeZone);
        
        Date date = new Date(0);
        DateFormat format_z = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S z");
        DateFormat format_Z = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S Z");
        
        String with_z = format_z.format(date);
        System.out.println(with_z);
        Date from_z = format_z.parse(with_z);
        System.out.println(Long.toString(from_z.getTime()));
                
        String with_Z = format_Z.format(date);
        System.out.println(with_Z);
        Date from_Z = format_Z.parse(with_Z);
        System.out.println(Long.toString(from_Z.getTime()));
        
        System.out.println(Boolean.toString(from_z.getTime() == from_Z.getTime()));
        System.out.println();
    }
        
    public static void main(String[] args) throws Exception {
        tryOneTimeZone("GMT+1");
        tryOneTimeZone("GMT+01");
        tryOneTimeZone("GMT+100");
        tryOneTimeZone("GMT+0100");
        tryOneTimeZone("GMT+1:00");
        tryOneTimeZone("GMT+01:00");
        tryOneTimeZone("Europe/London");
    }
    
}

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

Comments
EVALUATION As of 1970-01-01 in Europe/London, its GMT offset was +0100 and its time zone abbreviation should be BST. Here's the zone definition of London in the Olson zone info. # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Europe/London -0:01:15 - LMT 1847 Dec 1 0:00 GB-Eire %s 1968 Oct 27 1:00 - BST 1971 Oct 31 2:00u 0:00 GB-Eire %s 1996 0:00 EU GMT/BST However, the time zone display name support in Java can't handle historical name changes due to the API design limitation. Closing this CR as a duplicate of 4255109.
05-06-2006