Java での SimpleTimeZone クラスの使用に問題があります。まず、JavaDoc は優れていますが、開始ルールと終了ルールに関して理解するのは簡単ではありません。しかし、ウェブで見つかったいくつかの例の助けを借りて、私はそれを正しくすることができました(なぜ8がday_of_monthで月の第2週を表すのかまだわかりません!!!しかし何でも)
今、私が理解していることを検証するための簡単な 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 日曜日の午前 2 時に開始します DST は 11 月の第 1 日曜日の午前 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 が DST にないことを教えてくれます... !!!!???
2012-11-04 00:59:59 と入力すると、テストに合格しました。
この 1 時間のギャップは私を困惑させます... 誰かこの動作を説明できますか?
ああ、ところで、誰かが詳しく説明できれば:
est.setStartRule(Calendar.MARCH, 8, -Calendar.SUNDAY, 2 * 60 * 60 * 1000);
なぜ 8 は 3 月の第 2 週を意味するのか...そして -SUNDAY. 実際のカレンダーの例では、このことを理解できません!!!
ありがとう