我在 Java 中使用 SimpleTimeZone 类时遇到问题。首先,JavaDoc 很好,但在开始和结束规则方面不太容易理解。但是在网上找到的一些例子的帮助下,我设法做对了(我仍然不明白为什么 8 代表 day_of_month 一个月的第二周!!!但无论如何)
现在我编写了一个简单的 Junit 测试来验证我的理解:
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()));
}
}
好的,我想测试日期限制,看看 inDaylightTime 是否返回正确的东西!
所以,我的规则是:
DST 开始于 3 月的第二个星期日凌晨 2 点 DST 结束于 11 月的第一个星期日凌晨 2 点
在 2012 年(现在)这给了我们 3 月 11 日凌晨 2 点和 11 月 4 日凌晨 2 点
你可以看到我的考试日期设置正确!!!
那么这是我的测试运行的输出:
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>
我的第一个断言失败了,并告诉我 2012-11-04 01:59:59 不是 inDST ... !!!!!!???
如果我输入 2012-11-04 00:59:59,则测试通过!
这 1 小时的间隔让我很困惑……谁能解释这种行为?
哦,顺便说一句,如果有人可以详细说明:
est.setStartRule(Calendar.MARCH, 8, -Calendar.SUNDAY, 2 * 60 * 60 * 1000);
为什么 8 表示三月的第二周......以及 -SUNDAY。我无法在一个真实的日历示例中弄清楚这件事!!!
谢谢