JDK-4348987 : Daylight saving problems in BET
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util:i18n
  • Affected Version: 1.1.8
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_nt
  • CPU: x86
  • Submitted: 2000-06-28
  • Updated: 2000-07-10
  • Resolved: 2000-07-10
Related Reports
Duplicate :  
Relates :  
Description

Name: sl110371			Date: 06/28/2000


java version "1.1.8"

I'm in Brazil and I?m trying to use daylight saving with JDK1.1.8. The switch
time happens at 00:00 hrs. If we set the start switch date in Oct, 8th  2000
00:00:00 and the end switch date to March , 5th 2000 00:00:00.
In the start switch date we expect the following times:

  Sat Oct 07 22:00:00 GMT-3 2000
  Sat Oct 07 23:00:00 GMT-3 2000
  Sun Oct 08 01:00:00 GMT-2 2000
  Sun Oct 08 02:00:00 GMT-2 2000

And in the end switch date we expect the following times:

  Sat Mar 04 22:00:00 GMT-02:00 2000
  Sat Mar 04 23:00:00 GMT-02:00 2000
  Sat Mar 04 23:00:00 GMT-03:00 2000
  Sun Mar 05 00:00:00 GMT-03:00 2000
  Sun Mar 05 01:00:00 GMT-03:00 2000

I'm using the Brazilian TimeZone ("BET") and setting the daylight saving as
explained above:

  SimpleTimeZone pdt = (SimpleTimeZone)TimeZone.getTimeZone("BET");
  Locale aLocale = new Locale("pt", "BR");
  Locale.setDefault(aLocale);
  pdt.setStartRule(9, 2, 1, 0);
  pdt.setEndRule(2, 1, 1, 0);
  TimeZone.setDefault(pdt);

And the behavior of the dates in the end switch date is:

  Sat Mar 04 22:00:00 GMT-02:00 2000
  Sat Mar 04 23:00:00 GMT-02:00 2000
  Sun Mar 05 00:00:00 GMT-02:00 2000
  Sun Mar 05 00:00:00 GMT-03:00 2000
  Sun Mar 05 01:00:00 GMT-03:00 2000

And for the start switch date, if I do a

  Date aDate = new Date(100,9,7,24,0,0);
  System.out.println("new Date(100,9,7,24,0,0): " + aDate.toString());
  aDate = new Date(aDate,2000,9,8,0,0,0);
  System.out.println("new Date(100,9,8,0,0,0): " + aDate.toString());

The output is:

  new Date(100,9,7,24,0,0): Sun Oct 08 01:00:00 PDT 2000
  new Date(100,9,8,0,0,0): Sat Oct 07 23:00:00 PST 2000

I have tried the following test

  SimpleTimeZone pdt = (SimpleTimeZone)TimeZone.getTimeZone("PST");
  Locale.setDefault(aLocale);
  pdt.setStartRule(9, 2, 1, 0);
  pdt.setEndRule(2, 1, 1, 0);
  TimeZone.setDefault(pdt);

The behavior is the same, when I do a new Date in the non existing hour of the
short day (new Date(aDate,2000,9,8,0,0,0);) instead of go to the Sun Oct 08
01:00:00 PDT 2000 it goes to Sat Oct 07 23:00:00 PST 2000. And in the long day
it goes twice to Sun Mar 05 00:00:00 instead of  Sat Mar 04 23:00:00.

Does anyone have any idea? Any suggestion would be very important to us.
Thanks in advance.

Source code:

import java.io.File;
import java.util.Vector;
import java.util.SimpleTimeZone;
import java.util.TimeZone;
import java.util.Locale;
import java.util.Calendar;
import java.util.Date;
import java.text.SimpleDateFormat;

public class TestDriver implements Runnable
{
    public final int YEAR = Calendar.YEAR;
    public final int MONTH = Calendar.MONTH;
    public final int DATE = Calendar.DATE;
    public final int HOUR = Calendar.HOUR;
    public final int MINUTE = Calendar.MINUTE;
    public final int SECOND = Calendar.SECOND;
    
    public static void main(String[] args)
    {
        Thread thread = new Thread(new TestDriver());
        thread.start();
    }
    public void add (Date aDate, int i, int unit)
    {
        Calendar myCalendar = (Calendar)Calendar.getInstance();
        myCalendar.setTime(aDate);
        myCalendar.setFirstDayOfWeek(Calendar.SUNDAY);
        myCalendar.setMinimalDaysInFirstWeek(7);
        myCalendar.set(unit, myCalendar.get(unit) + i);
        aDate.setTime(myCalendar.getTime().getTime());
    }
    public void set(Date aDate, int year, int month, int date, int hour, int
    minute, int second)
    {
        Calendar myCalendar = (Calendar)Calendar.getInstance();
        myCalendar.set(year, month, date, hour, minute, second);
        myCalendar.setFirstDayOfWeek(Calendar.SUNDAY);
        myCalendar.setMinimalDaysInFirstWeek(7);
        aDate.setTime(myCalendar.getTime().getTime());
        myCalendar.add(HOUR, 1);
    }

    public void run()
    {
            Date aDate = new Date();
            // Start 9;2;1;0 08/10/2000 00:00
            // End   2;1;1;0 05/03/2000 00:00

            SimpleTimeZone pdt = (SimpleTimeZone)TimeZone.getTimeZone("BET");
            Locale aLocale = new Locale("pt", "BR");
            Locale.setDefault(aLocale);
            pdt.setStartRule(9, 2, 1, 0);
            pdt.setEndRule(2, 1, 1, 0);
            TimeZone.setDefault(pdt);
            SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm zz",
                                                        aLocale);

            System.out.println();
            System.out.println("Start 9;2;1;0 08/10/2000 00:00");
            System.out.println("End   2;1;1;0 05/03/2000 00:00");
            System.out.println();
            System.out.println("Constructor:");
            this.set(aDate,2000,1,23,0,0,0);
            System.out.println("new Date(100,1,23,0,0,0): " + sdf.format
(aDate));
            this.set(aDate,2000,2,4,22,0,0);
            System.out.println("new Date(100,2,4,22,0,0): " + sdf.format
(aDate));
            this.set(aDate,2000,2,4,23,0,0);
            System.out.println("new Date(100,2,4,23,0,0): " + sdf.format
(aDate));
            this.set(aDate,2000,2,4,24,0,0);
            System.out.println("new Date(100,2,4,24,0,0): " + sdf.format
(aDate));
            this.set(aDate,2000,2,5,0,0,0);
            System.out.println("new Date(100,2,5,0,0,0): " + sdf.format(aDate));
            this.set(aDate,2000,2,5,1,0,0);
            System.out.println("new Date(100,2,5,1,0,0): " + sdf.format(aDate));
            this.set(aDate,2000,4,10,0,0,0);
            System.out.println("new Date(100,4,10,0,0,0): " + sdf.format
(aDate));
            this.set(aDate,2000,9,7,23,0,0);
            System.out.println("new Date(100,9,7,23,0,0): " + sdf.format
(aDate));
            this.set(aDate,2000,9,8,0,0,0);
            System.out.println("new Date(100,9,8,0,0,0): " + sdf.format(aDate));
            this.set(aDate,2000,9,8,1,0,0);
            System.out.println("new Date(100,9,8,1,0,0): " + sdf.format(aDate));
            this.set(aDate,2000,10,23,0,0,0);
            System.out.println("new Date(100,10,23,0,0,0): " + sdf.format
(aDate));

            System.out.println();
            System.out.println("Add minute:");
            this.set(aDate,2000,1,23,0,0,0);
            System.out.println("new Date(100,1,23,0,0,0): " + sdf.format
(aDate));
            this.add(aDate, 1, this.MINUTE);
            System.out.println("add(1,MINUTE): " + sdf.format(aDate));
            this.set(aDate,2000,2,4,22,59,0);
            System.out.println("new Date(100,2,4,22,59,0): " + sdf.format
(aDate));
            this.add(aDate, 1, this.MINUTE);
            System.out.println("add(1,MINUTE): " + sdf.format(aDate));
            this.set(aDate,2000,2,4,23,59,0);
            System.out.println("new Date(100,2,4,23,59,0): " + sdf.format
(aDate));
            this.add(aDate, 1, this.MINUTE);
            System.out.println("add(1,MINUTE): " + sdf.format(aDate));
            this.set(aDate,2000,2,5,0,0,0);
            System.out.println("new Date(100,2,5,0,0,0): " + sdf.format(aDate));
            this.add(aDate, 1, this.MINUTE);
            System.out.println("add(1,MINUTE): " + sdf.format(aDate));
            this.set(aDate,2000,4,10,0,0,0);
            System.out.println("new Date(100,4,10,0,0,0): " + sdf.format
(aDate));
            this.add(aDate, 1, this.MINUTE);
            System.out.println("add(1,MINUTE): " + sdf.format(aDate));
            this.set(aDate,2000,9,7,23,59,0);
            System.out.println("new Date(100,9,7,23,59,0): " + sdf.format
(aDate));
            this.add(aDate, 1, this.MINUTE);
            System.out.println("add(1,MINUTE): " + sdf.format(aDate));
            this.set(aDate,2000,9,8,0,0,0);
            System.out.println("new Date(100,9,8,0,0,0): " + sdf.format(aDate));
            this.add(aDate, 1, this.MINUTE);
            System.out.println("add(1,MINUTE): " + sdf.format(aDate));
            this.set(aDate,2000,10,23,0,0,0);
            System.out.println("new Date(100,10,23,0,0,0): " + sdf.format
(aDate));
            this.add(aDate, 1, this.MINUTE);
            System.out.println("add(1,MINUTE): " + sdf.format(aDate));
    }
}

Output:

Start 9;2;1;0 08/10/2000 00:00
End   2;1;1;0 05/03/2000 00:00

Constructor:
new Date(100,1,23,0,0,0): 23/02/2000 00:00 GMT-02:00
new Date(100,2,4,22,0,0): 04/03/2000 22:00 GMT-02:00
new Date(100,2,4,23,0,0): 04/03/2000 23:00 GMT-02:00
new Date(100,2,4,24,0,0): 05/03/2000 00:00 GMT-02:00
new Date(100,2,5,0,0,0): 05/03/2000 00:00 GMT-03:00
new Date(100,2,5,1,0,0): 05/03/2000 01:00 GMT-03:00
new Date(100,4,10,0,0,0): 10/05/2000 00:00 GMT-03:00
new Date(100,9,7,23,0,0): 07/10/2000 23:00 GMT-03:00
new Date(100,9,8,0,0,0): 07/10/2000 23:00 GMT-03:00
new Date(100,9,8,1,0,0): 08/10/2000 01:00 GMT-02:00
new Date(100,10,23,0,0,0): 23/11/2000 00:00 GMT-02:00

Add minute:
new Date(100,1,23,0,0,0): 23/02/2000 00:00 GMT-02:00
add(1,MINUTE): 23/02/2000 00:01 GMT-02:00
new Date(100,2,4,22,59,0): 04/03/2000 22:59 GMT-02:00
add(1,MINUTE): 04/03/2000 23:00 GMT-02:00
new Date(100,2,4,23,59,0): 04/03/2000 23:59 GMT-02:00
add(1,MINUTE): 05/03/2000 00:00 GMT-02:00
new Date(100,2,5,0,0,0): 05/03/2000 00:00 GMT-03:00
add(1,MINUTE): 05/03/2000 00:01 GMT-03:00
new Date(100,4,10,0,0,0): 10/05/2000 00:00 GMT-03:00
add(1,MINUTE): 10/05/2000 00:01 GMT-03:00
new Date(100,9,7,23,59,0): 07/10/2000 23:59 GMT-03:00
add(1,MINUTE): 08/10/2000 01:00 GMT-02:00
new Date(100,9,8,0,0,0): 07/10/2000 23:00 GMT-03:00
add(1,MINUTE): 07/10/2000 23:01 GMT-03:00
new Date(100,10,23,0,0,0): 23/11/2000 00:00 GMT-02:00
add(1,MINUTE): 23/11/2000 00:01 GMT-02:00
(Review ID: 106615) 
======================================================================

Comments
WORK AROUND Name: sl110371 Date: 06/28/2000 To bypass the problem in the start switch day: public void set(Date aDate, int year, int month, int date, int hour, int minute, int second) { Calendar myCalendar = (Calendar)Calendar.getInstance(); // Start 9;2;1;0 08/10/2000 00:00 if (month == 9 && date == 8 && year == 2000 && hour == 0 && minute == 0 && second == 0) { hour = 24; date = date - 1; } myCalendar.set(year, month, date, hour, minute, second); myCalendar.setFirstDayOfWeek(Calendar.SUNDAY); myCalendar.setMinimalDaysInFirstWeek(7); aDate.setTime(myCalendar.getTime().getTime()); myCalendar.add(HOUR, 1); } ======================================================================
11-06-2004

EVALUATION I can't even tell from the javadoc how setEndRule should work. The description of the time argument says it's in daylight time, but the example in the method description uses standard time. norbert.lindenberg@Eng 2000-06-29 The BET time zone definition in 1.1.8 is not up-to-date. It is in 1.1.8: new SimpleTimeZone(-3 * millisPerHour, "America/Sao_Paulo" /*E%sT*/, Calendar.OCTOBER, 1, -Calendar.SUNDAY /*DOW>=DOM*/, 0 * millisPerHour, Calendar.FEBRUARY, 11, -Calendar.SUNDAY /*DOW>=DOM*/, 0 * millisPerHour, 1 * millisPerHour), The latest one is: new SimpleTimeZone(-3*ONE_HOUR, "America/Sao_Paulo", /*BR%sT*/ Calendar.OCTOBER, 1, -Calendar.SUNDAY /*DOW>=DOM*/, 0*ONE_HOUR, Calendar.FEBRUARY, -1, Calendar.SUNDAY /*DOW_IN_MON*/, 0*ONE_HOUR, 1*ONE_HOUR), The rules to be given to setStartRule() and setEndRule() should follow the latest rules. For methods arguments documentation, refer to the API doc of the SimpleTimeZone constructor (with 10 args). masayoshi.okutsu@Eng 2000-06-30 I was looking at the javadoc in J2SDK 1.3 for the method using in the description, SimpleTimeZone.setEndRule(int, int, int, int). It still has the inconsistency that I mentioned above. norbert.lindenberg@Eng 2000-07-05 According to Decretos at http://pcdsh01.on.br/, DST ended on Feb. 27, 2000 0:00am local (wall) time. The DST rules above are guesses as described in the Olson public source. # Decree <a href="http://pcdsh01.on.br/figuras/HV3150.gif">3,150</a> # (1999-08-23) adopted by same states. # Decree <a href="http://pcdsh01.on.br/DecHV99.gif">3,188</a> (1999-09-30) # adds SE, AL, PE, PR, RN, CE, PI, MA and RR. # These give only one year's rules. After that, the rules are guesses # and are quite possibly wrong, but are more likely than no DST at all. Rule Brazil 1999 max - Oct Sun>=1 0:00 1:00 S Rule Brazil 2000 max - Feb lastSun 0:00 0 - The parameters with setStartRule() and setEndRule() for the latest DST schedule in the Olson public source are: pdt.setStartRule(Calendar.OCTOBER, 1, -Calendar.SUNDAY, 0); pdt.setEndRule(Calendar.FEBRUARY, -1, Calendar.SUNDAY, 0); The output is: Start 9;2;1;0 08/10/2000 00:00 End 2;1;1;0 05/03/2000 00:00 Constructor: new Date(100,1,23,0,0,0): 23/02/2000 00:00 GMT-02:00 new Date(100,2,4,22,0,0): 04/03/2000 22:00 GMT-03:00 new Date(100,2,4,23,0,0): 04/03/2000 23:00 GMT-03:00 new Date(100,2,4,24,0,0): 05/03/2000 00:00 GMT-03:00 new Date(100,2,5,0,0,0): 05/03/2000 00:00 GMT-03:00 new Date(100,2,5,1,0,0): 05/03/2000 01:00 GMT-03:00 new Date(100,4,10,0,0,0): 10/05/2000 00:00 GMT-03:00 new Date(100,9,7,23,0,0): 07/10/2000 23:00 GMT-02:00 new Date(100,9,8,0,0,0): 08/10/2000 00:00 GMT-02:00 new Date(100,9,8,1,0,0): 08/10/2000 01:00 GMT-02:00 new Date(100,10,23,0,0,0): 23/11/2000 00:00 GMT-02:00 Add minute: new Date(100,1,23,0,0,0): 23/02/2000 00:00 GMT-02:00 add(1,MINUTE): 23/02/2000 00:01 GMT-02:00 new Date(100,2,4,22,59,0): 04/03/2000 22:59 GMT-03:00 add(1,MINUTE): 04/03/2000 23:00 GMT-03:00 new Date(100,2,4,23,59,0): 04/03/2000 23:59 GMT-03:00 add(1,MINUTE): 05/03/2000 00:00 GMT-03:00 new Date(100,2,5,0,0,0): 05/03/2000 00:00 GMT-03:00 add(1,MINUTE): 05/03/2000 00:01 GMT-03:00 new Date(100,4,10,0,0,0): 10/05/2000 00:00 GMT-03:00 add(1,MINUTE): 10/05/2000 00:01 GMT-03:00 new Date(100,9,7,23,59,0): 07/10/2000 23:59 GMT-02:00 add(1,MINUTE): 08/10/2000 00:00 GMT-02:00 new Date(100,9,8,0,0,0): 08/10/2000 00:00 GMT-02:00 add(1,MINUTE): 08/10/2000 00:01 GMT-02:00 new Date(100,10,23,0,0,0): 23/11/2000 00:00 GMT-02:00 add(1,MINUTE): 23/11/2000 00:01 GMT-02:00 masayoshi.okutsu@Eng 2000-07-10 Filed the documentation problem as bug id 4351653. The problem of having the old DST schedule is a duplicate of 4328609. Closing this bug as a duplicate. masayoshi.okutsu@Eng 2000-07-10
10-07-2000