JDK-4312621 : (cal) API: DST transition handling is ambiguous in GregorianCalendar
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util:i18n
  • Affected Version:
    1.1.6,1.1.8,1.2.0,1.2.2,1.3.0,1.3.1,1.4.0,1.4.1,5.0,5.0u8,6 1.1.6,1.1.8,1.2.0,1.2.2,1.3.0,1.3.1,1.4.0,1.4.1,5.0,5.0u8,6
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS:
    generic,linux,solaris_8,solaris_9,windows_nt,windows_2000,windows_xp generic,linux,solaris_8,solaris_9,windows_nt,windows_2000,windows_xp
  • CPU: generic,x86,sparc
  • Submitted: 2000-02-15
  • Updated: 2017-02-10
Related Reports
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
At a transition between a standard time and daylight saving time, handling of calendar fields is ambiguous. It's necessary to be able to specify wall, standard, daylight saving time in GregorianCalendar to disambiguate fields and operations, such as add/roll.

Refer to tm_isdst spec of mktime() in the C library.

Name: krC82822			Date: 11/28/2000


28 Nov 2000, eval1127@eng -- 4248500 -> 4312621.
----------------
java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)


I wrote a method that return the date for yesterday.
It has been working fine all month, but failed today.
I believe the roll() method has a bug.
The code to demonstrate this is here:

import java.util.Date;
import java.util.Calendar;
import java.util.GregorianCalendar;

public class DateTest {

	public static void main(String[] args) {

		GregorianCalendar cal = new GregorianCalendar();
		Date today = cal.getTime();
		System.out.println("today: " + today);

		cal.roll(Calendar.DATE,false);
		Date yesterday = cal.getTime();
		System.out.println("yesterday: " + yesterday);
	}
}


When run, it produces this output:

today: Wed Nov 01 10:18:52 PST 2000
yesterday: Thu Nov 30 10:18:52 PST 2000


As you can see today is 1-Nov-2000, but yesterday
is 30-Nov-2000. It should be 31-Oct-2000.

So I changed the program to use the add() method,
instead of roll(). It looks like this

import java.util.Date;
import java.util.Calendar;
import java.util.GregorianCalendar;

public class DateTest {

	public static void main(String[] args) {

		GregorianCalendar cal = new GregorianCalendar();
		Date today = cal.getTime();
		System.out.println("today: " + today);

		cal.add(Calendar.DATE,-1);
		Date yesterday = cal.getTime();
		System.out.println("yesterday: " + yesterday);
	}
}

This version produces the following result:

today: Wed Nov 01 10:23:07 PST 2000
yesterday: Tue Oct 31 10:23:07 PST 2000

Which is what I would expect.
(Review ID: 111696)
======================================================================

Name: yyT116575			Date: 07/17/2001


java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)

I have a column in Oralce database of date type. I have a data as '01-04-2001 02:00:00' of the format 'dd-mm-yyyy hh24:mi:ss'. When i read the program in java using 3rd party JDBC driver, i am getting the value of the date field as '01-04-2001 01:00:00'. Any time between 2.00AM to 2.59AM is shifted by one hour automatically. I suspect it is due to day light saving option enabled in my system. But even if i disable the daylight saving option, it is happening like this.How can fix this bug?

To explain this...

I have two objects date and time separately showing
the date and time for April 1st 2001 2 AM. I
concatanated these two strings and parsed in to a Date
object. Then the result shows again that it is 1st
April 2001 1 AM, the same old result!!!!.

java.sql.Time time = rs.getTime(1); 
java.sql.Date date = rs.getDate(1); 

System.out.println(time.toString()); //02:00:00
System.out.println(date.toString()); //2001-04-01

SimpleDateFormat sdf = new
SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

java.util.Date date1 =
sdf.parse(date.toString().trim() + " " +
time.toString().trim());

System.out.println(new
Timestamp(date1.getTime()).toString()); //2001-04-01
01:00:00.0
(Review ID: 128200)
======================================================================

Comments
WORK AROUND Name: krC82822 Date: 11/28/2000 Use the add() method, instead of roll(). (Review ID: 111696) ======================================================================
2004-08-21

EVALUATION The following is from Solaris mktime man page. GregorianCalendar needs to support a similar interface to disambiguate given time. If tm_isdst is positive, the original values are assumed to be in the alternate timezone. If it turns out that the alternate timezone is not valid for the computed calendar time, then the components are adjusted to the main timezone. Likewise, if tm_isdst is zero, the original values are assumed to be in the main timezone and are converted to the alternate timezone if the main timezone is not valid. If tm_isdst is negative, mktime() attempts to determine whether the alternate timezone is in effect for the specified time. masayoshi.okutsu@Eng 2000-02-15
2000-02-15