I Have an issue with the use of SimpleTimeZone class in Java. First, the JavaDoc is nice but not quite easy to understand in regards of the start and end Rules. But with the help of some example found on the web, i managed to get it right (i still don't understand why 8 represents the second week of a month in day_of_month!!! but whatever)
Now i have written a simple Junit test to validate what i understand:
package test;
import static org.junit.Assert.assertEquals;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.SimpleTimeZone;
import org.apache.log4j.Logger;
import org.junit.Test;
public class SimpleTimeZoneTest {
Logger log = Logger.getLogger(SimpleTimeZoneTest.class);
@Test
public void testTimeZoneWithDST() throws Exception {
Calendar testDateEndOut = new GregorianCalendar(2012, Calendar.NOVEMBER, 4, 01, 59, 59);
Calendar testDateEndIn = new GregorianCalendar(2012, Calendar.NOVEMBER, 4, 02, 00, 00);
Calendar testDateStartOut = new GregorianCalendar(2012, Calendar.MARCH, 11, 01, 59, 59);
Calendar testDateStartIn = new GregorianCalendar(2012, Calendar.MARCH, 11, 02, 00, 00);
SimpleTimeZone est = new SimpleTimeZone(-5 * 60 * 60 * 1000, "EST");
est.setStartRule(Calendar.MARCH, 8, -Calendar.SUNDAY, 2 * 60 * 60 * 1000);
est.setEndRule(Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2 * 60 * 60 * 1000);
Calendar theCal = new GregorianCalendar(est);
theCal.setTimeInMillis(testDateEndOut.getTimeInMillis());
log.info(" Cal date = " + new Timestamp(theCal.getTimeInMillis()) + " : " + theCal.getTimeZone().getDisplayName());
log.info(" Cal use DST = " + theCal.getTimeZone().useDaylightTime());
log.info(" Cal In DST = " + theCal.getTimeZone().inDaylightTime(theCal.getTime()));
log.info("offset = " + theCal.getTimeZone().getOffset(theCal.getTimeInMillis()));
log.info("DTS offset= " + theCal.getTimeZone().getDSTSavings());
assertEquals("End date Should be In DST", true, theCal.getTimeZone().inDaylightTime(theCal.getTime()));
theCal.setTimeInMillis(testDateEndIn.getTimeInMillis());
log.info(" Cal date = " + new Timestamp(theCal.getTimeInMillis()) + " : " + theCal.getTimeZone().getDisplayName());
log.info(" Cal use DST = " + theCal.getTimeZone().useDaylightTime());
log.info(" Cal In DST = " + theCal.getTimeZone().inDaylightTime(theCal.getTime()));
log.info("offset = " + theCal.getTimeZone().getOffset(theCal.getTimeInMillis()));
log.info("DTS offset= " + theCal.getTimeZone().getDSTSavings());
assertEquals("End date Should be Out DST", false, theCal.getTimeZone().inDaylightTime(theCal.getTime()));
theCal.setTimeInMillis(testDateStartIn.getTimeInMillis());
log.info(" Cal date = " + new Timestamp(theCal.getTimeInMillis()) + " : " + theCal.getTimeZone().getDisplayName());
log.info(" Cal use DST = " + theCal.getTimeZone().useDaylightTime());
log.info(" Cal In DST = " + theCal.getTimeZone().inDaylightTime(theCal.getTime()));
log.info("offset = " + theCal.getTimeZone().getOffset(theCal.getTimeInMillis()));
log.info("DTS offset= " + theCal.getTimeZone().getDSTSavings());
assertEquals("Start date Should be in DST", true, theCal.getTimeZone().inDaylightTime(theCal.getTime()));
theCal.setTimeInMillis(testDateStartOut.getTimeInMillis());
log.info(" Cal date = " + new Timestamp(theCal.getTimeInMillis()) + " : " + theCal.getTimeZone().getDisplayName());
log.info(" Cal use DST = " + theCal.getTimeZone().useDaylightTime());
log.info(" Cal In DST = " + theCal.getTimeZone().inDaylightTime(theCal.getTime()));
log.info("offset = " + theCal.getTimeZone().getOffset(theCal.getTimeInMillis()));
log.info("DTS offset= " + theCal.getTimeZone().getDSTSavings());
assertEquals("Start date Should be Out DST", false, theCal.getTimeZone().inDaylightTime(theCal.getTime()));
}
}
Ok, i want to test the date limits to see if the inDaylightTime return the right thing!
So, my rules are :
DST start the second sunday of March at 2am
DST end the first sunday of november at 2am
In 2012 (now) this give us the march 11 at 2am and November 4 at 2am
You can see my test dates are set properly!!!
Well here is the output of my test run:
2012-11-01 18:22:44,344 INFO [test.SimpleTimeZoneTest] - < Cal date = 2012-11-04 01:59:59.0 : Eastern Standard Time>
2012-11-01 18:22:44,345 INFO [test.SimpleTimeZoneTest] - < Cal use DST = true>
2012-11-01 18:22:44,345 INFO [test.SimpleTimeZoneTest] - < Cal In DST = false>
2012-11-01 18:22:44,345 INFO [test.SimpleTimeZoneTest] - <offset = -18000000>
2012-11-01 18:22:44,345 INFO [test.SimpleTimeZoneTest] - <DTS offset= 3600000>
My first assert just fails and tell me that 2012-11-04 01:59:59 is not inDST... !!!!???
If i put 2012-11-04 00:59:59, the test pass!
This 1 hour gap just puzzle me... can anyone explain this behavior?
Oh, btw, if anyone could elaborate on the :
est.setStartRule(Calendar.MARCH, 8, -Calendar.SUNDAY, 2 * 60 * 60 * 1000);
Why 8 means second week of march... and the -SUNDAY. I can't figure out this thing on a real calendar example!!!
Thanks