1 /* 2 * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos 3 * 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * * Redistributions of source code must retain the above copyright notice, 10 * this list of conditions and the following disclaimer. 11 * 12 * * Redistributions in binary form must reproduce the above copyright notice, 13 * this list of conditions and the following disclaimer in the documentation 14 * and/or other materials provided with the distribution. 15 * 16 * * Neither the name of JSR-310 nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 package org.threeten.bp.zone; 33 34 import static org.testng.Assert.assertEquals; 35 import static org.testng.Assert.assertNotNull; 36 import static org.threeten.bp.DayOfWeek.FRIDAY; 37 import static org.threeten.bp.DayOfWeek.MONDAY; 38 import static org.threeten.bp.DayOfWeek.SATURDAY; 39 import static org.threeten.bp.DayOfWeek.SUNDAY; 40 import static org.threeten.bp.DayOfWeek.THURSDAY; 41 import static org.threeten.bp.DayOfWeek.TUESDAY; 42 import static org.threeten.bp.Month.APRIL; 43 import static org.threeten.bp.Month.AUGUST; 44 import static org.threeten.bp.Month.FEBRUARY; 45 import static org.threeten.bp.Month.MARCH; 46 import static org.threeten.bp.Month.MAY; 47 import static org.threeten.bp.Month.NOVEMBER; 48 import static org.threeten.bp.Month.OCTOBER; 49 import static org.threeten.bp.Month.SEPTEMBER; 50 import static org.threeten.bp.zone.ZoneOffsetTransitionRule.TimeDefinition.STANDARD; 51 import static org.threeten.bp.zone.ZoneOffsetTransitionRule.TimeDefinition.UTC; 52 import static org.threeten.bp.zone.ZoneOffsetTransitionRule.TimeDefinition.WALL; 53 54 import java.util.List; 55 56 import org.testng.annotations.Test; 57 import org.threeten.bp.DateTimeException; 58 import org.threeten.bp.LocalDateTime; 59 import org.threeten.bp.LocalTime; 60 import org.threeten.bp.Month; 61 import org.threeten.bp.Year; 62 import org.threeten.bp.ZoneOffset; 63 import org.threeten.bp.zone.ZoneOffsetTransitionRule.TimeDefinition; 64 65 /** 66 * Test ZoneRulesBuilder. 67 */ 68 @Test 69 public class TestZoneRulesBuilder { 70 71 private static final ZoneOffset OFFSET_1 = ZoneOffset.ofHours(1); 72 private static final ZoneOffset OFFSET_2 = ZoneOffset.ofHours(2); 73 private static final ZoneOffset OFFSET_1_15 = ZoneOffset.ofHoursMinutes(1, 15); 74 private static final ZoneOffset OFFSET_2_30 = ZoneOffset.ofHoursMinutes(2, 30); 75 private static final int PERIOD_0 = 0; 76 private static final int PERIOD_1HOUR = 60 * 60; 77 private static final int PERIOD_1HOUR30MIN = ((1 * 60) + 30) * 60; 78 private static final LocalDateTime DATE_TIME_FIRST = dateTime(Year.MIN_VALUE, 1, 1, 0, 0); 79 private static final LocalDateTime DATE_TIME_LAST = dateTime(Year.MAX_VALUE, 12, 31, 23, 59); 80 private static final LocalDateTime DATE_TIME_2008_01_01 = dateTime(2008, 1, 1, 0, 0); 81 private static final LocalDateTime DATE_TIME_2008_07_01 = dateTime(2008, 7, 1, 0, 0); 82 83 //----------------------------------------------------------------------- 84 // toRules() 85 //----------------------------------------------------------------------- 86 @Test(expectedExceptions=IllegalStateException.class) test_toRules_noWindows()87 public void test_toRules_noWindows() { 88 ZoneRulesBuilder b = new ZoneRulesBuilder(); 89 b.toRules("Europe/London"); 90 } 91 92 @Test(expectedExceptions=NullPointerException.class) test_toRules_null()93 public void test_toRules_null() { 94 ZoneRulesBuilder b = new ZoneRulesBuilder(); 95 b.addWindowForever(OFFSET_2_30); 96 b.toRules(null); 97 } 98 99 //----------------------------------------------------------------------- 100 // Combined 101 //----------------------------------------------------------------------- 102 @Test test_combined_singleCutover()103 public void test_combined_singleCutover() { 104 ZoneRulesBuilder b = new ZoneRulesBuilder(); 105 b.addWindow(OFFSET_1, dateTime(1950, 1, 1, 1, 0), STANDARD); 106 b.addWindowForever(OFFSET_2); 107 ZoneRules test = b.toRules("Europe/London"); 108 assertOffsetInfo(test, DATE_TIME_FIRST, OFFSET_1); 109 assertGap(test, 1950, 1, 1, 1, 30, OFFSET_1, OFFSET_2); 110 assertOffsetInfo(test, DATE_TIME_LAST, OFFSET_2); 111 } 112 113 @Test test_combined_localFixedRules()114 public void test_combined_localFixedRules() { 115 ZoneRulesBuilder b = new ZoneRulesBuilder(); 116 b.addWindow(OFFSET_1_15, dateTime(1920, 1, 1, 1, 0), WALL); 117 b.addWindow(OFFSET_1, dateTime(1950, 1, 1, 1, 0), WALL); 118 b.addWindowForever(OFFSET_1); 119 b.addRuleToWindow(2000, Year.MAX_VALUE, MARCH, -1, SUNDAY, time(1, 0), false, WALL, PERIOD_1HOUR30MIN); 120 b.addRuleToWindow(2000, Year.MAX_VALUE, OCTOBER, -1, SUNDAY, time(1, 0), false, WALL, PERIOD_0); 121 ZoneRules test = b.toRules("Europe/London"); 122 assertOffsetInfo(test, DATE_TIME_FIRST, OFFSET_1_15); 123 assertOverlap(test, 1920, 1, 1, 0, 55, OFFSET_1_15, OFFSET_1); 124 assertOffsetInfo(test, DATE_TIME_LAST, OFFSET_1); 125 assertOffsetInfo(test, dateTime(1800, 7, 1, 1, 0), OFFSET_1_15); 126 assertOffsetInfo(test, dateTime(1920, 1, 1, 1, 0), OFFSET_1); 127 assertOffsetInfo(test, dateTime(1960, 1, 1, 1, 0), OFFSET_1); 128 assertOffsetInfo(test, dateTime(2000, 1, 1, 1, 0), OFFSET_1); 129 assertOffsetInfo(test, DATE_TIME_2008_01_01, OFFSET_1); 130 assertOffsetInfo(test, DATE_TIME_2008_07_01, OFFSET_2_30); 131 assertGap(test, 2008, 3, 30, 1, 20, OFFSET_1, OFFSET_2_30); 132 assertOverlap(test, 2008, 10, 26, 0, 20, OFFSET_2_30, OFFSET_1); 133 } 134 135 @Test test_combined_windowChangeDuringDST()136 public void test_combined_windowChangeDuringDST() { 137 ZoneRulesBuilder b = new ZoneRulesBuilder(); 138 b.addWindow(OFFSET_1, dateTime(2000, 7, 1, 1, 0), WALL); 139 b.addWindowForever(OFFSET_1); 140 b.addRuleToWindow(2000, Year.MAX_VALUE, MARCH, -1, SUNDAY, time(1, 0), false, WALL, PERIOD_1HOUR); 141 b.addRuleToWindow(2000, Year.MAX_VALUE, OCTOBER, -1, SUNDAY, time(2, 0), false, WALL, PERIOD_0); 142 ZoneRules test = b.toRules("Europe/Dublin"); 143 assertOffsetInfo(test, DATE_TIME_FIRST, OFFSET_1); 144 assertOffsetInfo(test, DATE_TIME_LAST, OFFSET_1); 145 146 assertOffsetInfo(test, dateTime(2000, 1, 1, 0, 0), OFFSET_1); 147 assertOffsetInfo(test, dateTime(2000, 7, 1, 0, 0), OFFSET_1); 148 assertGap(test, 2000, 7, 1, 1, 20, OFFSET_1, OFFSET_2); 149 assertOffsetInfo(test, dateTime(2000, 7, 1, 3, 0), OFFSET_2); 150 assertOverlap(test, 2000, 10, 29, 1, 20, OFFSET_2, OFFSET_1); 151 assertOffsetInfo(test, dateTime(2000, 12, 1, 0, 0), OFFSET_1); 152 } 153 154 @Test test_combined_windowChangeWithinDST()155 public void test_combined_windowChangeWithinDST() { 156 ZoneRulesBuilder b = new ZoneRulesBuilder(); 157 b.addWindow(OFFSET_1, dateTime(2000, 7, 1, 1, 0), WALL); 158 b.addWindow(OFFSET_1, dateTime(2000, 8, 1, 2, 0), WALL); 159 b.addRuleToWindow(2000, Year.MAX_VALUE, MARCH, -1, SUNDAY, time(1, 0), false, WALL, PERIOD_1HOUR); 160 b.addRuleToWindow(2000, Year.MAX_VALUE, OCTOBER, -1, SUNDAY, time(2, 0), false, WALL, PERIOD_0); 161 b.addWindowForever(OFFSET_1); 162 ZoneRules test = b.toRules("Europe/Dublin"); 163 assertOffsetInfo(test, DATE_TIME_FIRST, OFFSET_1); 164 assertOffsetInfo(test, DATE_TIME_LAST, OFFSET_1); 165 166 assertOffsetInfo(test, dateTime(2000, 1, 1, 0, 0), OFFSET_1); 167 assertOffsetInfo(test, dateTime(2000, 7, 1, 0, 0), OFFSET_1); 168 assertGap(test, 2000, 7, 1, 1, 20, OFFSET_1, OFFSET_2); 169 assertOffsetInfo(test, dateTime(2000, 7, 1, 3, 0), OFFSET_2); 170 assertOverlap(test, 2000, 8, 1, 1, 20, OFFSET_2, OFFSET_1); 171 assertOffsetInfo(test, dateTime(2000, 12, 1, 0, 0), OFFSET_1); 172 } 173 174 @Test test_combined_endsInSavings()175 public void test_combined_endsInSavings() { 176 ZoneRulesBuilder b = new ZoneRulesBuilder(); 177 b.addWindow(OFFSET_1_15, dateTime(1920, 1, 1, 1, 0), WALL); 178 b.addWindowForever(OFFSET_1); 179 b.addRuleToWindow(2000, Year.MAX_VALUE, MARCH, -1, SUNDAY, time(1, 0), false, WALL, PERIOD_0); 180 b.addRuleToWindow(2000, Year.MAX_VALUE, OCTOBER, -1, SUNDAY, time(1, 0), false, WALL, PERIOD_1HOUR); 181 ZoneRules test = b.toRules("Pacific/Auckland"); 182 assertOffsetInfo(test, DATE_TIME_FIRST, OFFSET_1_15); 183 assertOffsetInfo(test, DATE_TIME_LAST, OFFSET_2); 184 assertOverlap(test, 1920, 1, 1, 0, 55, OFFSET_1_15, OFFSET_1); 185 assertOffsetInfo(test, dateTime(2000, 3, 26, 0, 59), OFFSET_1); 186 assertOffsetInfo(test, dateTime(2000, 3, 26, 1, 00), OFFSET_1); 187 assertGap(test, 2000, 10, 29, 1, 20, OFFSET_1, OFFSET_2); 188 assertOverlap(test, 2001, 3, 25, 0, 20, OFFSET_2, OFFSET_1); 189 assertGap(test, 2001, 10, 28, 1, 20, OFFSET_1, OFFSET_2); 190 } 191 192 @Test test_combined_closeTransitions()193 public void test_combined_closeTransitions() { 194 ZoneRulesBuilder b = new ZoneRulesBuilder(); 195 b.addWindow(OFFSET_1, dateTime(1920, 1, 1, 1, 0), WALL); 196 b.addWindowForever(OFFSET_1); 197 b.addRuleToWindow(2000, MARCH, 20, time(2, 0), false, WALL, PERIOD_1HOUR); 198 b.addRuleToWindow(2000, MARCH, 20, time(4, 2), false, WALL, PERIOD_0); 199 ZoneRules test = b.toRules("Europe/London"); 200 assertOffsetInfo(test, DATE_TIME_FIRST, OFFSET_1); 201 assertOffsetInfo(test, DATE_TIME_LAST, OFFSET_1); 202 assertOffsetInfo(test, dateTime(2000, 3, 20, 1, 59), OFFSET_1); 203 assertGap(test, 2000, 3, 20, 2, 0, OFFSET_1, OFFSET_2); 204 assertGap(test, 2000, 3, 20, 2, 59, OFFSET_1, OFFSET_2); 205 assertOffsetInfo(test, dateTime(2000, 3, 20, 3, 0), OFFSET_2); 206 assertOffsetInfo(test, dateTime(2000, 3, 20, 3, 1), OFFSET_2); 207 assertOverlap(test, 2000, 3, 20, 3, 2, OFFSET_2, OFFSET_1); 208 assertOverlap(test, 2000, 3, 20, 4, 1, OFFSET_2, OFFSET_1); 209 assertOffsetInfo(test, dateTime(2000, 3, 20, 4, 2), OFFSET_1); 210 } 211 212 @Test test_combined_closeTransitionsMeet()213 public void test_combined_closeTransitionsMeet() { 214 ZoneRulesBuilder b = new ZoneRulesBuilder(); 215 b.addWindow(OFFSET_1, dateTime(1920, 1, 1, 1, 0), WALL); 216 b.addWindowForever(OFFSET_1); 217 b.addRuleToWindow(2000, MARCH, 20, time(2, 0), false, WALL, PERIOD_1HOUR); 218 b.addRuleToWindow(2000, MARCH, 20, time(4, 0), false, WALL, PERIOD_0); 219 ZoneRules test = b.toRules("Europe/London"); 220 assertOffsetInfo(test, DATE_TIME_FIRST, OFFSET_1); 221 assertOffsetInfo(test, DATE_TIME_LAST, OFFSET_1); 222 assertOffsetInfo(test, dateTime(2000, 3, 20, 1, 59), OFFSET_1); 223 assertGap(test, 2000, 3, 20, 2, 0, OFFSET_1, OFFSET_2); 224 assertGap(test, 2000, 3, 20, 2, 59, OFFSET_1, OFFSET_2); 225 assertOverlap(test, 2000, 3, 20, 3, 0, OFFSET_2, OFFSET_1); 226 assertOverlap(test, 2000, 3, 20, 3, 59, OFFSET_2, OFFSET_1); 227 assertOffsetInfo(test, dateTime(2000, 3, 20, 4, 0), OFFSET_1); 228 } 229 230 // TODO: handle conflicting gap/overlap 231 // public void test_combined_closeTransitionsConflictPartly() { 232 // TransitionRulesBuilder b = new TransitionRulesBuilder(OFFSET_1, dateTime(1920, 1, 1, 1, 0), WALL); 233 // b.addWindowForever(OFFSET_1); 234 // b.addRuleToWindow(2000, MARCH, 20, time(2, 0), WALL, PERIOD_1HOUR); 235 // b.addRuleToWindow(2000, MARCH, 20, time(3, 30), WALL, PERIOD_0); 236 // ZoneRules test = b.toRules("Europe/London"); 237 // assertOffsetInfo(test, DATE_TIME_FIRST), OFFSET_1); 238 // assertOffsetInfo(test, DATE_TIME_LAST), OFFSET_1); 239 // assertOffsetInfo(test, dateTime(2000, 3, 20, 1, 59)), OFFSET_1); 240 // assertGap(test, 2000, 3, 20, 2, 0, OFFSET_1, OFFSET_2); 241 // assertGap(test, 2000, 3, 20, 2, 29, OFFSET_1, OFFSET_2); 242 // assertOffsetInfo(test, dateTime(2000, 3, 20, 2, 30)), OFFSET_1); 243 // assertOffsetInfo(test, dateTime(2000, 3, 20, 2, 59)), OFFSET_1); 244 // assertOverlap(test, 2000, 3, 20, 3, 0, OFFSET_2, OFFSET_1); 245 // assertOverlap(test, 2000, 3, 20, 3, 29, OFFSET_2, OFFSET_1); 246 // assertOffsetInfo(test, dateTime(2000, 3, 20, 3, 30)), OFFSET_1); 247 // } 248 249 @Test test_combined_weirdSavingsBeforeLast()250 public void test_combined_weirdSavingsBeforeLast() { 251 ZoneRulesBuilder b = new ZoneRulesBuilder(); 252 b.addWindow(OFFSET_1, dateTime(1920, 1, 1, 1, 0), WALL); 253 b.addWindowForever(OFFSET_1); 254 b.addRuleToWindow(1998, MARCH, 20, time(2, 0), false, WALL, PERIOD_1HOUR30MIN); 255 b.addRuleToWindow(2000, Year.MAX_VALUE, MARCH, 20, null, time(2, 0), false, WALL, PERIOD_1HOUR); 256 b.addRuleToWindow(2000, Year.MAX_VALUE, OCTOBER, 20, null, time(2, 0), false, WALL, PERIOD_0); 257 ZoneRules test = b.toRules("Europe/London"); 258 259 assertOffsetInfo(test, DATE_TIME_FIRST, OFFSET_1); 260 assertOffsetInfo(test, DATE_TIME_LAST, OFFSET_1); 261 262 assertOffsetInfo(test, dateTime(1999, 1, 1, 0, 0), OFFSET_2_30); 263 assertOverlap(test, 2000, 3, 20, 1, 30, OFFSET_2_30, OFFSET_2); 264 assertOverlap(test, 2000, 10, 20, 1, 30, OFFSET_2, OFFSET_1); 265 assertGap(test, 2001, 3, 20, 2, 30, OFFSET_1, OFFSET_2); 266 assertOverlap(test, 2001, 10, 20, 1, 30, OFFSET_2, OFFSET_1); 267 } 268 269 @Test test_combined_differentLengthLastRules1()270 public void test_combined_differentLengthLastRules1() { 271 ZoneRulesBuilder b = new ZoneRulesBuilder(); 272 b.addWindow(OFFSET_1, dateTime(1920, 1, 1, 1, 0), WALL); 273 b.addWindowForever(OFFSET_1); 274 b.addRuleToWindow(1998, MARCH, 20, time(2, 0), false, WALL, PERIOD_1HOUR); 275 b.addRuleToWindow(1998, Year.MAX_VALUE, OCTOBER, 30, null, time(2, 0), false, WALL, PERIOD_0); 276 b.addRuleToWindow(1999, MARCH, 21, time(2, 0), false, WALL, PERIOD_1HOUR); 277 b.addRuleToWindow(2000, MARCH, 22, time(2, 0), false, WALL, PERIOD_1HOUR); 278 b.addRuleToWindow(2001, MARCH, 23, time(2, 0), false, WALL, PERIOD_1HOUR); 279 b.addRuleToWindow(2002, Year.MAX_VALUE, MARCH, 24, null, time(2, 0), false, WALL, PERIOD_1HOUR); 280 ZoneRules test = b.toRules("Europe/London"); 281 282 assertOffsetInfo(test, DATE_TIME_FIRST, OFFSET_1); 283 assertOffsetInfo(test, DATE_TIME_LAST, OFFSET_1); 284 285 assertGap(test, 1998, 3, 20, 2, 30, OFFSET_1, OFFSET_2); 286 assertOverlap(test, 1998, 10, 30, 1, 30, OFFSET_2, OFFSET_1); 287 assertGap(test, 1999, 3, 21, 2, 30, OFFSET_1, OFFSET_2); 288 assertOverlap(test, 1999, 10, 30, 1, 30, OFFSET_2, OFFSET_1); 289 assertGap(test, 2000, 3, 22, 2, 30, OFFSET_1, OFFSET_2); 290 assertOverlap(test, 2000, 10, 30, 1, 30, OFFSET_2, OFFSET_1); 291 assertGap(test, 2001, 3, 23, 2, 30, OFFSET_1, OFFSET_2); 292 assertOverlap(test, 2001, 10, 30, 1, 30, OFFSET_2, OFFSET_1); 293 assertGap(test, 2002, 3, 24, 2, 30, OFFSET_1, OFFSET_2); 294 assertOverlap(test, 2002, 10, 30, 1, 30, OFFSET_2, OFFSET_1); 295 assertGap(test, 2003, 3, 24, 2, 30, OFFSET_1, OFFSET_2); 296 assertOverlap(test, 2003, 10, 30, 1, 30, OFFSET_2, OFFSET_1); 297 assertGap(test, 2004, 3, 24, 2, 30, OFFSET_1, OFFSET_2); 298 assertOverlap(test, 2004, 10, 30, 1, 30, OFFSET_2, OFFSET_1); 299 assertGap(test, 2005, 3, 24, 2, 30, OFFSET_1, OFFSET_2); 300 assertOverlap(test, 2005, 10, 30, 1, 30, OFFSET_2, OFFSET_1); 301 } 302 303 @Test test_combined_differentLengthLastRules2()304 public void test_combined_differentLengthLastRules2() { 305 ZoneRulesBuilder b = new ZoneRulesBuilder(); 306 b.addWindow(OFFSET_1, dateTime(1920, 1, 1, 1, 0), WALL); 307 b.addWindowForever(OFFSET_1); 308 b.addRuleToWindow(1998, Year.MAX_VALUE, MARCH, 30, null, time(2, 0), false, WALL, PERIOD_1HOUR); 309 b.addRuleToWindow(1998, OCTOBER, 20, time(2, 0), false, WALL, PERIOD_0); 310 b.addRuleToWindow(1999, OCTOBER, 21, time(2, 0), false, WALL, PERIOD_0); 311 b.addRuleToWindow(2000, OCTOBER, 22, time(2, 0), false, WALL, PERIOD_0); 312 b.addRuleToWindow(2001, OCTOBER, 23, time(2, 0), false, WALL, PERIOD_0); 313 b.addRuleToWindow(2002, Year.MAX_VALUE, OCTOBER, 24, null, time(2, 0), false, WALL, PERIOD_0); 314 ZoneRules test = b.toRules("Europe/London"); 315 316 assertOffsetInfo(test, DATE_TIME_FIRST, OFFSET_1); 317 assertOffsetInfo(test, DATE_TIME_LAST, OFFSET_1); 318 319 assertGap(test, 1998, 3, 30, 2, 30, OFFSET_1, OFFSET_2); 320 assertOverlap(test, 1998, 10, 20, 1, 30, OFFSET_2, OFFSET_1); 321 assertGap(test, 1999, 3, 30, 2, 30, OFFSET_1, OFFSET_2); 322 assertOverlap(test, 1999, 10, 21, 1, 30, OFFSET_2, OFFSET_1); 323 assertGap(test, 2000, 3, 30, 2, 30, OFFSET_1, OFFSET_2); 324 assertOverlap(test, 2000, 10, 22, 1, 30, OFFSET_2, OFFSET_1); 325 assertGap(test, 2001, 3, 30, 2, 30, OFFSET_1, OFFSET_2); 326 assertOverlap(test, 2001, 10, 23, 1, 30, OFFSET_2, OFFSET_1); 327 assertGap(test, 2002, 3, 30, 2, 30, OFFSET_1, OFFSET_2); 328 assertOverlap(test, 2002, 10, 24, 1, 30, OFFSET_2, OFFSET_1); 329 assertGap(test, 2003, 3, 30, 2, 30, OFFSET_1, OFFSET_2); 330 assertOverlap(test, 2003, 10, 24, 1, 30, OFFSET_2, OFFSET_1); 331 assertGap(test, 2004, 3, 30, 2, 30, OFFSET_1, OFFSET_2); 332 assertOverlap(test, 2004, 10, 24, 1, 30, OFFSET_2, OFFSET_1); 333 assertGap(test, 2005, 3, 30, 2, 30, OFFSET_1, OFFSET_2); 334 assertOverlap(test, 2005, 10, 24, 1, 30, OFFSET_2, OFFSET_1); 335 } 336 337 @Test test_twoChangesSameDay()338 public void test_twoChangesSameDay() { 339 // ensures that TZRule.compare works 340 ZoneOffset plus2 = ZoneOffset.ofHours(2); 341 ZoneOffset plus3 = ZoneOffset.ofHours(3); 342 ZoneRulesBuilder b = new ZoneRulesBuilder(); 343 b.addWindowForever(plus2); 344 b.addRuleToWindow(2010, 2010, SEPTEMBER, 10, null, time(12, 0), false, STANDARD, PERIOD_1HOUR); 345 b.addRuleToWindow(2010, 2010, SEPTEMBER, 10, null, time(23, 0), false, STANDARD, PERIOD_0); 346 ZoneRules test = b.toRules("Africa/Cairo"); 347 348 assertOffsetInfo(test, DATE_TIME_FIRST, plus2); 349 assertOffsetInfo(test, DATE_TIME_LAST, plus2); 350 351 assertGap(test, 2010, 9, 10, 12, 0, plus2, plus3); // jump forward from 12:00 to 13:00 on Tue 10th Sep 352 assertOverlap(test, 2010, 9, 10, 23, 0, plus3, plus2); // overlaps from Wed 11th Sep 00:00 back to Tue 10th Sep 23:00 353 } 354 355 @Test test_twoChangesDifferentDefinition()356 public void test_twoChangesDifferentDefinition() { 357 // ensures that TZRule.compare works 358 ZoneOffset plus2 = ZoneOffset.ofHours(2); 359 ZoneOffset plus3 = ZoneOffset.ofHours(3); 360 ZoneRulesBuilder b = new ZoneRulesBuilder(); 361 b.addWindowForever(plus2); 362 b.addRuleToWindow(2010, 2010, SEPTEMBER, -1, TUESDAY, time(0, 0), false, STANDARD, PERIOD_1HOUR); 363 b.addRuleToWindow(2010, 2010, SEPTEMBER, 29, null, time(23, 0), false, STANDARD, PERIOD_0); 364 ZoneRules test = b.toRules("Africa/Cairo"); 365 366 assertOffsetInfo(test, DATE_TIME_FIRST, plus2); 367 assertOffsetInfo(test, DATE_TIME_LAST, plus2); 368 369 assertGap(test, 2010, 9, 28, 0, 0, plus2, plus3); // jump forward from 00:00 to 01:00 on Tue 28th Sep 370 assertOverlap(test, 2010, 9, 29, 23, 0, plus3, plus2); // overlaps from Thu 30th Sep 00:00 back to Wed 29th Sep 23:00 371 } 372 373 //----------------------------------------------------------------------- 374 @Test test_argentina()375 public void test_argentina() { 376 // # On October 3, 1999, 0:00 local, Argentina implemented daylight savings time, 377 // # which did not result in the switch of a time zone, as they stayed 9 hours 378 // # from the International Date Line. 379 // Rule Arg 1989 1993 - Mar Sun>=1 0:00 0 - 380 // Rule Arg 1989 1992 - Oct Sun>=15 0:00 1:00 S 381 // Rule Arg 1999 only - Oct Sun>=1 0:00 1:00 S 382 // Rule Arg 2000 only - Mar 3 0:00 0 - 383 // Zone America/Argentina/Tucuman -4:20:52 - LMT 1894 Oct 31 384 // -3:00 Arg AR%sT 1999 Oct 3 385 // -4:00 Arg AR%sT 2000 Mar 3 386 387 ZoneOffset minus3 = ZoneOffset.ofHours(-3); 388 ZoneOffset minus4 = ZoneOffset.ofHours(-4); 389 ZoneRulesBuilder b = new ZoneRulesBuilder(); 390 b.addWindow(minus3, dateTime(1900, 1, 1, 0, 0), WALL); 391 b.addWindow(minus3, dateTime(1999, 10, 3, 0, 0), WALL); 392 b.addRuleToWindow(1993, MARCH, 3, time(0, 0), false, WALL, PERIOD_0); 393 b.addRuleToWindow(1999, OCTOBER, 3, time(0, 0), false, WALL, PERIOD_1HOUR); 394 b.addRuleToWindow(2000, MARCH, 3, time(0, 0), false, WALL, PERIOD_0); 395 b.addWindow(minus4, dateTime(2000, 3, 3, 0, 0), WALL); 396 b.addRuleToWindow(1993, MARCH, 3, time(0, 0), false, WALL, PERIOD_0); 397 b.addRuleToWindow(1999, OCTOBER, 3, time(0, 0), false, WALL, PERIOD_1HOUR); 398 b.addRuleToWindow(2000, MARCH, 3, time(0, 0), false, WALL, PERIOD_0); 399 b.addWindowForever(minus3); 400 ZoneRules test = b.toRules("America/Argentina/Tucuman"); 401 402 assertOffsetInfo(test, DATE_TIME_FIRST, minus3); 403 assertOffsetInfo(test, DATE_TIME_LAST, minus3); 404 405 assertOffsetInfo(test, dateTime(1999, 10, 2, 22, 59), minus3); 406 assertOffsetInfo(test, dateTime(1999, 10, 2, 23, 59), minus3); 407 assertOffsetInfo(test, dateTime(1999, 10, 3, 0, 0), minus3); 408 assertOffsetInfo(test, dateTime(1999, 10, 3, 1, 0), minus3); 409 410 assertOffsetInfo(test, dateTime(2000, 3, 2, 22, 59), minus3); 411 assertOffsetInfo(test, dateTime(2000, 3, 2, 23, 59), minus3); 412 assertOffsetInfo(test, dateTime(2000, 3, 3, 0, 0), minus3); 413 assertOffsetInfo(test, dateTime(2000, 3, 3, 1, 0), minus3); 414 } 415 416 @Test test_cairo_dateChange()417 public void test_cairo_dateChange() { 418 // Rule Egypt 2008 max - Apr lastFri 0:00s 1:00 S 419 // Rule Egypt 2008 max - Aug lastThu 23:00s 0 - 420 // Zone Africa/Cairo 2:05:00 - LMT 1900 Oct 421 // 2:00 Egypt EE%sT 422 ZoneOffset plus2 = ZoneOffset.ofHours(2); 423 ZoneOffset plus3 = ZoneOffset.ofHours(3); 424 ZoneRulesBuilder b = new ZoneRulesBuilder(); 425 b.addWindowForever(plus2); 426 b.addRuleToWindow(2008, Year.MAX_VALUE, APRIL, -1, FRIDAY, time(0, 0), false, STANDARD, PERIOD_1HOUR); 427 b.addRuleToWindow(2008, Year.MAX_VALUE, AUGUST, -1, THURSDAY, time(23, 0), false, STANDARD, PERIOD_0); 428 ZoneRules test = b.toRules("Africa/Cairo"); 429 430 assertOffsetInfo(test, DATE_TIME_FIRST, plus2); 431 assertOffsetInfo(test, DATE_TIME_LAST, plus2); 432 433 assertGap(test, 2009, 4, 24, 0, 0, plus2, plus3); 434 assertOverlap(test, 2009, 8, 27, 23, 0, plus3, plus2); // overlaps from Fri 00:00 back to Thu 23:00 435 } 436 437 @Test test_cairo_twoChangesSameMonth()438 public void test_cairo_twoChangesSameMonth() { 439 // 2011i 440 // Rule Egypt 2010 only - Aug 11 0:00 0 - 441 // Rule Egypt 2010 only - Sep 10 0:00 1:00 S 442 // Rule Egypt 2010 only - Sep lastThu 23:00s 0 - 443 // Zone Africa/Cairo 2:05:00 - LMT 1900 Oct 444 // 2:00 Egypt EE%sT 445 ZoneOffset plus2 = ZoneOffset.ofHours(2); 446 ZoneOffset plus3 = ZoneOffset.ofHours(3); 447 ZoneRulesBuilder b = new ZoneRulesBuilder(); 448 b.addWindowForever(plus2); 449 b.addRuleToWindow(2010, 2010, AUGUST, 11, null, time(0, 0), false, STANDARD, PERIOD_0); 450 b.addRuleToWindow(2010, 2010, SEPTEMBER, 10, null, time(0, 0), false, STANDARD, PERIOD_1HOUR); 451 b.addRuleToWindow(2010, 2010, SEPTEMBER, -1, THURSDAY, time(23, 0), false, STANDARD, PERIOD_0); 452 ZoneRules test = b.toRules("Africa/Cairo"); 453 454 assertOffsetInfo(test, DATE_TIME_FIRST, plus2); 455 assertOffsetInfo(test, DATE_TIME_LAST, plus2); 456 457 assertGap(test, 2010, 9, 10, 0, 0, plus2, plus3); // jump forward from 00:00 to 01:00 on Fri 10th Sep 458 assertOverlap(test, 2010, 9, 30, 23, 0, plus3, plus2); // overlaps from Fri 1st Oct 00:00 back to Thu 30th Sep 23:00 (!!!) 459 } 460 461 @Test test_sofia_lastRuleClash()462 public void test_sofia_lastRuleClash() { 463 // UTC rule change in 1996 occurs after Wall change 464 // need to ensure that last rule is only applied to last window 465 // Rule E-Eur 1981 max - Mar lastSun 0:00 1:00 S 466 // Rule E-Eur 1996 max - Oct lastSun 0:00 0 - 467 // Rule EU 1981 max - Mar lastSun 1:00u 1:00 S 468 // Rule EU 1996 max - Oct lastSun 1:00u 0 - 469 // Zone Europe/Sofia 470 // 2:00 E-Eur EE%sT 1997 471 // 2:00 EU EE%sT 472 ZoneOffset plus2 = ZoneOffset.ofHours(2); 473 ZoneOffset plus3 = ZoneOffset.ofHours(3); 474 ZoneRulesBuilder b = new ZoneRulesBuilder(); 475 b.addWindow(plus2, dateTime(1997, 1, 1, 0, 0), WALL); 476 b.addRuleToWindow(1996, Year.MAX_VALUE, MARCH, -1, SUNDAY, time(1, 0), false, WALL, PERIOD_1HOUR); 477 b.addRuleToWindow(1996, Year.MAX_VALUE, OCTOBER, -1, SUNDAY, time(1, 0), false, WALL, PERIOD_0); 478 b.addWindowForever(plus2); 479 b.addRuleToWindow(1996, Year.MAX_VALUE, MARCH, -1, SUNDAY, time(1, 0), false, UTC, PERIOD_1HOUR); 480 b.addRuleToWindow(1996, Year.MAX_VALUE, OCTOBER, -1, SUNDAY, time(1, 0), false, UTC, PERIOD_0); 481 ZoneRules test = b.toRules("Europe/Sofia"); 482 483 assertOffsetInfo(test, DATE_TIME_FIRST, plus2); 484 assertOffsetInfo(test, DATE_TIME_LAST, plus2); 485 486 assertGap(test, 1996, 3, 31, 1, 0, plus2, plus3); 487 assertOverlap(test, 1996, 10, 27, 0, 0, plus3, plus2); 488 assertOffsetInfo(test, dateTime(1996, 10, 27, 1, 0), plus2); 489 assertOffsetInfo(test, dateTime(1996, 10, 27, 2, 0), plus2); 490 assertOffsetInfo(test, dateTime(1996, 10, 27, 3, 0), plus2); 491 assertOffsetInfo(test, dateTime(1996, 10, 27, 4, 0), plus2); 492 } 493 494 @Test test_prague()495 public void test_prague() { 496 // need to calculate savings applicable at window start based on 497 // first rule being transition from no savings to DST 498 // Rule C-Eur 1944 1945 - Apr Mon>=1 2:00s 1:00 S 499 // Rule C-Eur 1944 only - Oct 2 2:00s 0 - 500 // Rule C-Eur 1945 only - Sep 16 2:00s 0 - 501 // Rule Czech 1945 only - Apr 8 2:00s 1:00 S 502 // Rule Czech 1945 only - Nov 18 2:00s 0 - 503 // Zone Europe/Prague 0:57:44 - LMT 1850 504 // 0:57:44 - PMT 1891 Oct 505 // 1:00 C-Eur CE%sT 1944 Sep 17 2:00s 506 // 1:00 Czech CE%sT 1979 507 // 1:00 EU CE%sT 508 ZoneOffset plus1 = ZoneOffset.ofHours(1); 509 ZoneOffset plus2 = ZoneOffset.ofHours(2); 510 ZoneRulesBuilder b = new ZoneRulesBuilder(); 511 b.addWindow(plus1, dateTime(1944, 9, 17, 2, 0), STANDARD); 512 b.addRuleToWindow(1944, 1945, APRIL, 1, MONDAY, time(2, 0), false, STANDARD, PERIOD_1HOUR); 513 b.addRuleToWindow(1944, OCTOBER, 2, time(2, 0), false, STANDARD, PERIOD_0); 514 b.addRuleToWindow(1945, SEPTEMBER, 16, time(2, 0), false, STANDARD, PERIOD_0); 515 b.addWindow(plus1, dateTime(1979, 1, 1, 0, 0), WALL); 516 b.addRuleToWindow(1945, APRIL, 8, time(2, 0), false, STANDARD, PERIOD_1HOUR); 517 b.addRuleToWindow(1945, NOVEMBER, 18, time(2, 0), false, STANDARD, PERIOD_0); 518 b.addWindowForever(plus1); 519 ZoneRules test = b.toRules("Europe/Sofia"); 520 521 assertOffsetInfo(test, DATE_TIME_FIRST, plus1); 522 assertOffsetInfo(test, DATE_TIME_LAST, plus1); 523 524 assertGap(test, 1944, 4, 3, 2, 30, plus1, plus2); 525 assertOverlap(test, 1944, 9, 17, 2, 30, plus2, plus1); 526 assertOffsetInfo(test, dateTime(1944, 9, 17, 3, 30), plus1); 527 assertOffsetInfo(test, dateTime(1944, 9, 17, 4, 30), plus1); 528 assertGap(test, 1945, 4, 8, 2, 30, plus1, plus2); 529 assertOverlap(test, 1945, 11, 18, 2, 30, plus2, plus1); 530 } 531 532 @Test test_tbilisi()533 public void test_tbilisi() { 534 // has transition into and out of 1 year of permanent DST (Mar96-Oct97) 535 // where the date in the window and rule are the same 536 // this is weird because the wall time in the rule is amended by the actual 537 // wall time from the zone lines 538 // Rule E-EurAsia 1981 max - Mar lastSun 0:00 1:00 S 539 // Rule E-EurAsia 1979 1995 - Sep lastSun 0:00 0 - 540 // Rule E-EurAsia 1996 max - Oct lastSun 0:00 0 - 541 // Zone Asia/Tbilisi 2:59:16 - LMT 1880 542 // 4:00 E-EurAsia GE%sT 1996 Oct lastSun 543 // 4:00 1:00 GEST 1997 Mar lastSun 544 // 4:00 E-EurAsia GE%sT 2004 Jun 27 545 // 3:00 RussiaAsia GE%sT 2005 Mar lastSun 2:00 546 // 4:00 - GET 547 ZoneOffset plus4 = ZoneOffset.ofHours(4); 548 ZoneOffset plus5 = ZoneOffset.ofHours(5); 549 ZoneRulesBuilder b = new ZoneRulesBuilder(); 550 b.addWindow(plus4, dateTime(1996, 10, 27, 0, 0), WALL); 551 b.addRuleToWindow(1996, Year.MAX_VALUE, MARCH, -1, SUNDAY, time(0, 0), false, WALL, PERIOD_1HOUR); 552 b.addRuleToWindow(1996, Year.MAX_VALUE, OCTOBER, -1, SUNDAY, time(0, 0), false, WALL, PERIOD_0); 553 b.addWindow(plus4, dateTime(1997, 3, 30, 0, 0), WALL); 554 b.setFixedSavingsToWindow(PERIOD_1HOUR); 555 b.addWindowForever(plus4); 556 b.addRuleToWindow(1996, Year.MAX_VALUE, MARCH, -1, SUNDAY, time(0, 0), false, WALL, PERIOD_1HOUR); 557 b.addRuleToWindow(1996, Year.MAX_VALUE, OCTOBER, -1, SUNDAY, time(0, 0), false, WALL, PERIOD_0); 558 ZoneRules test = b.toRules("Europe/Sofia"); 559 560 assertOffsetInfo(test, DATE_TIME_FIRST, plus4); 561 assertOffsetInfo(test, DATE_TIME_LAST, plus4); 562 563 assertGap(test, 1996, 3, 31, 0, 30, plus4, plus5); 564 // assertOverlap(test, 1996, 10, 26, 23, 30, plus5, plus4); // fixed DST blocks overlap 565 assertOffsetInfo(test, dateTime(1996, 10, 26, 22, 30), plus5); 566 assertOffsetInfo(test, dateTime(1996, 10, 26, 23, 30), plus5); 567 assertOffsetInfo(test, dateTime(1996, 10, 27, 0, 30), plus5); 568 // assertOverlap(test, 1997, 3, 30, 0, 30, plus5, plus4); // end of fixed blocks overlap 569 assertOffsetInfo(test, dateTime(1997, 3, 29, 22, 30), plus5); 570 assertOffsetInfo(test, dateTime(1997, 3, 29, 23, 30), plus5); 571 assertOffsetInfo(test, dateTime(1997, 3, 30, 0, 30), plus5); 572 assertOffsetInfo(test, dateTime(1997, 3, 30, 1, 30), plus5); 573 assertOffsetInfo(test, dateTime(1997, 3, 30, 2, 30), plus5); 574 assertOverlap(test, 1997, 10, 25, 23, 30, plus5, plus4); 575 } 576 577 @Test test_vincennes()578 public void test_vincennes() { 579 // need to ensure that at least one real rule is added to expand on the last rule 580 // Rule US 2007 max - Mar Sun>=8 2:00 1:00 D 581 // Rule US 2007 max - Nov Sun>=1 2:00 0 S 582 // -5:00 - EST 2006 Apr 2 2:00 583 // -6:00 US C%sT 2007 Nov 4 2:00 584 // -5:00 US E%sT 585 ZoneOffset minus5 = ZoneOffset.ofHours(-5); 586 ZoneOffset minus6 = ZoneOffset.ofHours(-6); 587 ZoneRulesBuilder b = new ZoneRulesBuilder(); 588 b.addWindow(minus6, dateTime(2007, 11, 4, 2, 0), WALL); 589 b.addRuleToWindow(2007, Year.MAX_VALUE, MARCH, 8, SUNDAY, time(2, 0), false, WALL, PERIOD_1HOUR); 590 b.addRuleToWindow(2007, Year.MAX_VALUE, NOVEMBER, 1, SUNDAY, time(2, 0), false, WALL, PERIOD_0); 591 b.addWindowForever(minus5); 592 b.addRuleToWindow(2007, Year.MAX_VALUE, MARCH, 8, SUNDAY, time(2, 0), false, WALL, PERIOD_1HOUR); 593 b.addRuleToWindow(2007, Year.MAX_VALUE, NOVEMBER, 1, SUNDAY, time(2, 0), false, WALL, PERIOD_0); 594 ZoneRules test = b.toRules("America/Indiana/Vincennes"); 595 596 assertOffsetInfo(test, DATE_TIME_FIRST, minus6); 597 assertOffsetInfo(test, DATE_TIME_LAST, minus5); 598 599 assertOffsetInfo(test, dateTime(2007, 3, 11, 0, 0), minus6); 600 assertOffsetInfo(test, dateTime(2007, 3, 11, 1, 0), minus6); 601 assertGap(test, 2007, 3, 11, 2, 0, minus6, minus5); 602 assertOffsetInfo(test, dateTime(2007, 3, 11, 3, 0), minus5); 603 assertOffsetInfo(test, dateTime(2007, 3, 11, 4, 0), minus5); 604 assertOffsetInfo(test, dateTime(2007, 3, 11, 5, 0), minus5); 605 } 606 607 @Test test_iqaluit()608 public void test_iqaluit() { 609 // two hour overlap due to end of daylight and change of standard offset 610 // Rule Canada 1987 2006 - Apr Sun>=1 2:00 1:00 D 611 // Rule Canada 1974 2006 - Oct lastSun 2:00 0 S 612 // Rule NT_YK 1987 2006 - Apr Sun>=1 2:00 1:00 D 613 // Rule NT_YK 1980 2006 - Oct lastSun 2:00 0 S 614 // -5:00 NT_YK E%sT 1999 Oct 31 2:00 615 // -6:00 Canada C%sT 616 ZoneOffset minus4 = ZoneOffset.ofHours(-4); 617 ZoneOffset minus5 = ZoneOffset.ofHours(-5); 618 ZoneOffset minus6 = ZoneOffset.ofHours(-6); 619 ZoneRulesBuilder b = new ZoneRulesBuilder(); 620 b.addWindow(minus5, dateTime(1999, 10, 31, 2, 0), WALL); 621 b.addRuleToWindow(1987, Year.MAX_VALUE, APRIL, 1, SUNDAY, time(2, 0), false, WALL, PERIOD_1HOUR); 622 b.addRuleToWindow(1987, Year.MAX_VALUE, OCTOBER, -1, SUNDAY, time(2, 0), false, WALL, PERIOD_0); 623 b.addWindowForever(minus6); 624 b.addRuleToWindow(1987, Year.MAX_VALUE, APRIL, 1, SUNDAY, time(2, 0), false, WALL, PERIOD_1HOUR); 625 b.addRuleToWindow(1987, Year.MAX_VALUE, OCTOBER, -1, SUNDAY, time(2, 0), false, WALL, PERIOD_0); 626 ZoneRules test = b.toRules("America/Iqaluit"); 627 628 assertOffsetInfo(test, DATE_TIME_FIRST, minus5); 629 assertOffsetInfo(test, DATE_TIME_LAST, minus6); 630 631 assertOffsetInfo(test, dateTime(1999, 10, 30, 23, 0), minus4); 632 assertOverlap(test, 1999, 10, 31, 0, 0, minus4, minus6); 633 assertOverlap(test, 1999, 10, 31, 1, 0, minus4, minus6); 634 assertOverlap(test, 1999, 10, 31, 1, 59, minus4, minus6); 635 assertOffsetInfo(test, dateTime(1999, 10, 31, 2, 0), minus6); 636 assertOffsetInfo(test, dateTime(1999, 10, 31, 3, 0), minus6); 637 } 638 639 @Test test_jordan2400()640 public void test_jordan2400() { 641 // rule is 24:00 - this is simplified from the TZDB 642 // Rule Jordan 2002 max - Mar lastThu 24:00 1:00 S 643 // Rule Jordan 2002 max - Sep lastFri 0:00s 0 - 644 // # Zone NAME GMTOFF RULES FORMAT [UNTIL] 645 // 2:00 Jordan EE%sT 646 ZoneOffset plus2 = ZoneOffset.ofHours(2); 647 ZoneOffset plus3 = ZoneOffset.ofHours(3); 648 ZoneRulesBuilder b = new ZoneRulesBuilder(); 649 b.addWindowForever(plus2); 650 b.addRuleToWindow(2002, Year.MAX_VALUE, MARCH, -1, THURSDAY, time(0, 0), true, WALL, PERIOD_1HOUR); 651 b.addRuleToWindow(2002, Year.MAX_VALUE, SEPTEMBER, -1, FRIDAY, time(0, 0), false, STANDARD, PERIOD_0); 652 ZoneRules test = b.toRules("Asia/Amman"); 653 654 assertOffsetInfo(test, DATE_TIME_FIRST, plus2); 655 assertOffsetInfo(test, DATE_TIME_LAST, plus2); 656 657 assertGap(test, 2002, 3, 29, 0, 0, plus2, plus3); 658 assertOffsetInfo(test, dateTime(2002, 3, 28, 23, 0), plus2); 659 assertOffsetInfo(test, dateTime(2002, 3, 29, 1, 0), plus3); 660 661 assertOverlap(test, 2002, 9, 27, 0, 0, plus3, plus2); 662 assertOffsetInfo(test, dateTime(2002, 9, 26, 23, 0), plus3); 663 assertOffsetInfo(test, dateTime(2002, 9, 27, 1, 0), plus2); 664 } 665 666 @Test test_japan2500()667 public void test_japan2500() { 668 // cutover time overflows into next day 669 // Rule Japan 1948 only - May Sat>=1 24:00 1:00 D 670 // Rule Japan 1948 1951 - Sep Sat>=8 25:00 0 S 671 // Rule Japan 1949 only - Apr Sat>=1 24:00 1:00 D 672 // Rule Japan 1950 1951 - May Sat>=1 24:00 1:00 D 673 ZoneOffset plus9 = ZoneOffset.ofHours(9); 674 ZoneOffset plus10 = ZoneOffset.ofHours(10); 675 ZoneRulesBuilder b = new ZoneRulesBuilder(); 676 b.addWindowForever(plus9); 677 b.addRuleToWindow(1948, 1948, MAY, 1, SATURDAY, time(0, 0), true, WALL, PERIOD_1HOUR); 678 b.addRuleToWindow(1948, 1951, SEPTEMBER, 8, SATURDAY, time(1, 0), 1, WALL, PERIOD_0); 679 b.addRuleToWindow(1949, 1949, APRIL, 1, SATURDAY, time(0, 0), true, WALL, PERIOD_1HOUR); 680 b.addRuleToWindow(1950, 1951, MAY, 1, SATURDAY, time(0, 0), true, WALL, PERIOD_1HOUR); 681 ZoneRules test = b.toRules("Japan"); 682 assertOffsetInfo(test, DATE_TIME_FIRST, plus9); 683 assertOffsetInfo(test, DATE_TIME_LAST, plus9); 684 // Sat>=1 => May 1st 685 assertGap(test, 1948, 5, 2, 0, 0, plus9, plus10); 686 assertOffsetInfo(test, dateTime(1948, 5, 1, 23, 0), plus9); 687 assertOffsetInfo(test, dateTime(1948, 5, 2, 1, 0), plus10); 688 // Sat>=8 => September 11th 689 assertOverlap(test, 1948, 9, 12, 0, 0, plus10, plus9); 690 assertOffsetInfo(test, dateTime(1948, 9, 11, 23, 0), plus10); 691 assertOffsetInfo(test, dateTime(1948, 9, 12, 1, 0), plus9); 692 // Sat>=1 => May 2nd 693 assertGap(test, 1949, 4, 3, 0, 0, plus9, plus10); 694 assertOffsetInfo(test, dateTime(1949, 4, 2, 23, 0), plus9); 695 assertOffsetInfo(test, dateTime(1949, 4, 3, 1, 0), plus10); 696 } 697 698 //----------------------------------------------------------------------- 699 // addWindow() 700 //----------------------------------------------------------------------- 701 @Test test_addWindow_constrainedRules()702 public void test_addWindow_constrainedRules() { 703 ZoneRulesBuilder b = new ZoneRulesBuilder(); 704 b.addWindow(OFFSET_1, dateTime(1800, 7, 1, 0, 0), WALL); 705 b.addWindow(OFFSET_1, dateTime(2008, 6, 30, 0, 0), STANDARD); 706 b.addRuleToWindow(2000, Year.MAX_VALUE, MARCH, -1, SUNDAY, time(1, 0), false, WALL, PERIOD_1HOUR30MIN); 707 b.addRuleToWindow(2000, Year.MAX_VALUE, OCTOBER, -1, SUNDAY, time(1, 0), false, WALL, PERIOD_0); 708 ZoneRules test = b.toRules("Europe/London"); 709 assertOffsetInfo(test, DATE_TIME_FIRST, OFFSET_1); 710 assertOffsetInfo(test, DATE_TIME_LAST, OFFSET_2_30); 711 assertOffsetInfo(test, DATE_TIME_2008_01_01, OFFSET_1); 712 assertOffsetInfo(test, DATE_TIME_2008_07_01, OFFSET_2_30); 713 assertGap(test, 2000, 3, 26, 1, 30, OFFSET_1, OFFSET_2_30); 714 assertOverlap(test, 2000, 10, 29, 0, 30, OFFSET_2_30, OFFSET_1); 715 assertGap(test, 2008, 3, 30, 1, 30, OFFSET_1, OFFSET_2_30); 716 assertOffsetInfo(test, dateTime(2008, 10, 26, 0, 30), OFFSET_2_30); 717 } 718 719 @Test test_addWindow_noRules()720 public void test_addWindow_noRules() { 721 ZoneRulesBuilder b = new ZoneRulesBuilder(); 722 b.addWindow(OFFSET_1, dateTime(1800, 7, 1, 0, 0), WALL); 723 b.addWindow(OFFSET_1, dateTime(2008, 6, 30, 0, 0), STANDARD); 724 ZoneRules test = b.toRules("Europe/London"); 725 assertOffsetInfo(test, DATE_TIME_FIRST, OFFSET_1); 726 assertOffsetInfo(test, DATE_TIME_LAST, OFFSET_1); 727 assertOffsetInfo(test, DATE_TIME_2008_01_01, OFFSET_1); 728 assertOffsetInfo(test, DATE_TIME_2008_07_01, OFFSET_1); 729 } 730 731 @Test(expectedExceptions=NullPointerException.class) test_addWindow_nullOffset()732 public void test_addWindow_nullOffset() { 733 ZoneRulesBuilder b = new ZoneRulesBuilder(); 734 b.addWindow((ZoneOffset) null, dateTime(2008, 6, 30, 0, 0), STANDARD); 735 } 736 737 @Test(expectedExceptions=NullPointerException.class) test_addWindow_nullTime()738 public void test_addWindow_nullTime() { 739 ZoneRulesBuilder b = new ZoneRulesBuilder(); 740 b.addWindow(OFFSET_1, (LocalDateTime) null, STANDARD); 741 } 742 743 @Test(expectedExceptions=NullPointerException.class) test_addWindow_nullTimeDefinition()744 public void test_addWindow_nullTimeDefinition() { 745 ZoneRulesBuilder b = new ZoneRulesBuilder(); 746 b.addWindow(OFFSET_1, dateTime(2008, 6, 30, 0, 0), (TimeDefinition) null); 747 } 748 749 //----------------------------------------------------------------------- 750 // addWindowForever() 751 //----------------------------------------------------------------------- 752 @Test test_addWindowForever_noRules()753 public void test_addWindowForever_noRules() { 754 ZoneRulesBuilder b = new ZoneRulesBuilder(); 755 b.addWindowForever(OFFSET_1); 756 ZoneRules test = b.toRules("Europe/London"); 757 assertOffsetInfo(test, DATE_TIME_FIRST, OFFSET_1); 758 assertOffsetInfo(test, DATE_TIME_LAST, OFFSET_1); 759 assertOffsetInfo(test, DATE_TIME_2008_01_01, OFFSET_1); 760 assertOffsetInfo(test, DATE_TIME_2008_07_01, OFFSET_1); 761 } 762 763 @Test test_addWindowForever_rules()764 public void test_addWindowForever_rules() { 765 ZoneRulesBuilder b = new ZoneRulesBuilder(); 766 b.addWindowForever(OFFSET_1); 767 b.addRuleToWindow(2000, Year.MAX_VALUE, MARCH, -1, SUNDAY, time(1, 0), false, WALL, PERIOD_1HOUR30MIN); 768 b.addRuleToWindow(2000, Year.MAX_VALUE, OCTOBER, -1, SUNDAY, time(1, 0), false, WALL, PERIOD_0); 769 ZoneRules test = b.toRules("Europe/London"); 770 assertOffsetInfo(test, DATE_TIME_FIRST, OFFSET_1); 771 assertOffsetInfo(test, DATE_TIME_LAST, OFFSET_1); 772 assertOffsetInfo(test, DATE_TIME_2008_01_01, OFFSET_1); 773 assertOffsetInfo(test, DATE_TIME_2008_07_01, OFFSET_2_30); 774 assertGap(test, 2008, 3, 30, 1, 20, OFFSET_1, OFFSET_2_30); 775 assertOverlap(test, 2008, 10, 26, 0, 20, OFFSET_2_30, OFFSET_1); 776 } 777 778 @Test(expectedExceptions=NullPointerException.class) test_addWindowForever_nullOffset()779 public void test_addWindowForever_nullOffset() { 780 ZoneRulesBuilder b = new ZoneRulesBuilder(); 781 b.addWindowForever((ZoneOffset) null); 782 } 783 784 //----------------------------------------------------------------------- 785 // setFixedSavings() 786 //----------------------------------------------------------------------- 787 @Test test_setFixedSavingsToWindow()788 public void test_setFixedSavingsToWindow() { 789 ZoneRulesBuilder b = new ZoneRulesBuilder(); 790 b.addWindow(OFFSET_1, dateTime(1800, 7, 1, 0, 0), WALL); 791 b.addWindowForever(OFFSET_1); 792 b.setFixedSavingsToWindow(PERIOD_1HOUR30MIN); 793 ZoneRules test = b.toRules("Europe/London"); 794 assertOffsetInfo(test, DATE_TIME_FIRST, OFFSET_1); 795 assertOffsetInfo(test, DATE_TIME_LAST, OFFSET_2_30); 796 assertOffsetInfo(test, DATE_TIME_2008_01_01, OFFSET_2_30); 797 assertOffsetInfo(test, DATE_TIME_2008_07_01, OFFSET_2_30); 798 assertGap(test, 1800, 7, 1, 0, 0, OFFSET_1, OFFSET_2_30); 799 } 800 801 @Test test_setFixedSavingsToWindow_first()802 public void test_setFixedSavingsToWindow_first() { 803 ZoneRulesBuilder b = new ZoneRulesBuilder(); 804 b.addWindowForever(OFFSET_1); 805 b.setFixedSavingsToWindow(PERIOD_1HOUR30MIN); 806 ZoneRules test = b.toRules("Europe/London"); 807 assertOffsetInfo(test, DATE_TIME_FIRST, OFFSET_2_30); 808 assertOffsetInfo(test, DATE_TIME_LAST, OFFSET_2_30); 809 } 810 811 @Test(expectedExceptions=IllegalStateException.class) test_setFixedSavingsToWindow_noWindow()812 public void test_setFixedSavingsToWindow_noWindow() { 813 ZoneRulesBuilder b = new ZoneRulesBuilder(); 814 b.setFixedSavingsToWindow(PERIOD_1HOUR30MIN); 815 } 816 817 @Test(expectedExceptions=IllegalStateException.class) test_setFixedSavingsToWindow_cannotMixSavingsWithRule()818 public void test_setFixedSavingsToWindow_cannotMixSavingsWithRule() { 819 ZoneRulesBuilder b = new ZoneRulesBuilder(); 820 b.addWindowForever(OFFSET_1); 821 b.addRuleToWindow(2000, 2020, MARCH, -1, SUNDAY, time(1, 0), false, WALL, PERIOD_1HOUR30MIN); 822 b.setFixedSavingsToWindow(PERIOD_1HOUR30MIN); 823 } 824 825 @Test(expectedExceptions=IllegalStateException.class) test_setFixedSavingsToWindow_cannotMixSavingsWithLastRule()826 public void test_setFixedSavingsToWindow_cannotMixSavingsWithLastRule() { 827 ZoneRulesBuilder b = new ZoneRulesBuilder(); 828 b.addWindowForever(OFFSET_1); 829 b.addRuleToWindow(2000, Year.MAX_VALUE, MARCH, -1, SUNDAY, time(1, 0), false, WALL, PERIOD_1HOUR30MIN); 830 b.setFixedSavingsToWindow(PERIOD_1HOUR30MIN); 831 } 832 833 //----------------------------------------------------------------------- 834 // addRuleToWindow() 835 //----------------------------------------------------------------------- 836 @Test test_addRuleToWindow_endOfMonth()837 public void test_addRuleToWindow_endOfMonth() { 838 ZoneRulesBuilder b = new ZoneRulesBuilder(); 839 b.addWindowForever(OFFSET_1); 840 b.addRuleToWindow(2000, 2001, MARCH, -1, SUNDAY, time(1, 0), false, UTC, PERIOD_1HOUR); 841 b.addRuleToWindow(2000, 2001, OCTOBER, -1, SUNDAY, time(1, 0), false, UTC, PERIOD_0); 842 ZoneRules test = b.toRules("Europe/London"); 843 assertOffsetInfo(test, dateTime(1999, 7, 1, 0, 0), OFFSET_1); 844 845 assertOffsetInfo(test, dateTime(2000, 1, 1, 0, 0), OFFSET_1); 846 assertGap(test, 2000, 3, 26, 2, 30, OFFSET_1, OFFSET_2); 847 assertOffsetInfo(test, dateTime(2000, 7, 1, 0, 0), OFFSET_2); 848 assertOverlap(test, 2000, 10, 29, 2, 30, OFFSET_2, OFFSET_1); 849 850 assertOffsetInfo(test, dateTime(2001, 1, 1, 0, 0), OFFSET_1); 851 assertGap(test, 2001, 3, 25, 2, 30, OFFSET_1, OFFSET_2); 852 assertOffsetInfo(test, dateTime(2001, 7, 1, 0, 0), OFFSET_2); 853 assertOverlap(test, 2001, 10, 28, 2, 30, OFFSET_2, OFFSET_1); 854 855 assertOffsetInfo(test, dateTime(2002, 7, 1, 0, 0), OFFSET_1); 856 } 857 858 @Test test_addRuleToWindow_endOfMonthFeb()859 public void test_addRuleToWindow_endOfMonthFeb() { 860 ZoneRulesBuilder b = new ZoneRulesBuilder(); 861 b.addWindowForever(OFFSET_1); 862 b.addRuleToWindow(2004, 2005, FEBRUARY, -1, SUNDAY, time(1, 0), false, UTC, PERIOD_1HOUR); 863 b.addRuleToWindow(2004, 2005, OCTOBER, -1, SUNDAY, time(1, 0), false, UTC, PERIOD_0); 864 ZoneRules test = b.toRules("Europe/London"); 865 assertOffsetInfo(test, dateTime(2003, 7, 1, 0, 0), OFFSET_1); 866 867 assertOffsetInfo(test, dateTime(2004, 1, 1, 0, 0), OFFSET_1); 868 assertGap(test, 2004, 2, 29, 2, 30, OFFSET_1, OFFSET_2); // leap 869 assertOffsetInfo(test, dateTime(2004, 7, 1, 0, 0), OFFSET_2); 870 assertOverlap(test, 2004, 10, 31, 2, 30, OFFSET_2, OFFSET_1); 871 872 assertOffsetInfo(test, dateTime(2005, 1, 1, 0, 0), OFFSET_1); 873 assertGap(test, 2005, 2, 27, 2, 30, OFFSET_1, OFFSET_2); 874 assertOffsetInfo(test, dateTime(2005, 7, 1, 0, 0), OFFSET_2); 875 assertOverlap(test, 2005, 10, 30, 2, 30, OFFSET_2, OFFSET_1); 876 877 assertOffsetInfo(test, dateTime(2006, 7, 1, 0, 0), OFFSET_1); 878 } 879 880 @Test test_addRuleToWindow_fromDayOfMonth()881 public void test_addRuleToWindow_fromDayOfMonth() { 882 ZoneRulesBuilder b = new ZoneRulesBuilder(); 883 b.addWindowForever(OFFSET_1); 884 b.addRuleToWindow(2000, 2001, MARCH, 10, SUNDAY, time(1, 0), false, UTC, PERIOD_1HOUR); 885 b.addRuleToWindow(2000, 2001, OCTOBER, 10, SUNDAY, time(1, 0), false, UTC, PERIOD_0); 886 ZoneRules test = b.toRules("Europe/London"); 887 assertOffsetInfo(test, dateTime(1999, 7, 1, 0, 0), OFFSET_1); 888 889 assertOffsetInfo(test, dateTime(2000, 1, 1, 0, 0), OFFSET_1); 890 assertGap(test, 2000, 3, 12, 2, 30, OFFSET_1, OFFSET_2); 891 assertOffsetInfo(test, dateTime(2000, 7, 1, 0, 0), OFFSET_2); 892 assertOverlap(test, 2000, 10, 15, 2, 30, OFFSET_2, OFFSET_1); 893 894 assertOffsetInfo(test, dateTime(2001, 1, 1, 0, 0), OFFSET_1); 895 assertGap(test, 2001, 3, 11, 2, 30, OFFSET_1, OFFSET_2); 896 assertOffsetInfo(test, dateTime(2001, 7, 1, 0, 0), OFFSET_2); 897 assertOverlap(test, 2001, 10, 14, 2, 30, OFFSET_2, OFFSET_1); 898 899 assertOffsetInfo(test, dateTime(2002, 7, 1, 0, 0), OFFSET_1); 900 } 901 902 @Test(expectedExceptions=IllegalStateException.class) test_addRuleToWindow_noWindow()903 public void test_addRuleToWindow_noWindow() { 904 ZoneRulesBuilder b = new ZoneRulesBuilder(); 905 b.addRuleToWindow(2000, Year.MAX_VALUE, MARCH, -1, SUNDAY, time(1, 0), false, WALL, PERIOD_1HOUR30MIN); 906 } 907 908 @Test(expectedExceptions=IllegalStateException.class) test_addRuleToWindow_cannotMixRuleWithSavings()909 public void test_addRuleToWindow_cannotMixRuleWithSavings() { 910 ZoneRulesBuilder b = new ZoneRulesBuilder(); 911 b.addWindowForever(OFFSET_1); 912 b.setFixedSavingsToWindow(PERIOD_1HOUR30MIN); 913 b.addRuleToWindow(2000, Year.MAX_VALUE, MARCH, -1, SUNDAY, time(1, 0), false, WALL, PERIOD_1HOUR30MIN); 914 } 915 916 @Test(expectedExceptions=DateTimeException.class) test_addRuleToWindow_illegalYear1()917 public void test_addRuleToWindow_illegalYear1() { 918 ZoneRulesBuilder b = new ZoneRulesBuilder(); 919 b.addWindowForever(OFFSET_1); 920 b.addRuleToWindow(Year.MIN_VALUE - 1, 2008, MARCH, -1, SUNDAY, time(1, 0), false, WALL, PERIOD_1HOUR30MIN); 921 } 922 923 @Test(expectedExceptions=DateTimeException.class) test_addRuleToWindow_illegalYear2()924 public void test_addRuleToWindow_illegalYear2() { 925 ZoneRulesBuilder b = new ZoneRulesBuilder(); 926 b.addWindowForever(OFFSET_1); 927 b.addRuleToWindow(2000, Year.MIN_VALUE - 1, MARCH, -1, SUNDAY, time(1, 0), false, WALL, PERIOD_1HOUR30MIN); 928 } 929 930 @Test(expectedExceptions=IllegalArgumentException.class) test_addRuleToWindow_illegalDayOfMonth_tooSmall()931 public void test_addRuleToWindow_illegalDayOfMonth_tooSmall() { 932 ZoneRulesBuilder b = new ZoneRulesBuilder(); 933 b.addWindowForever(OFFSET_1); 934 b.addRuleToWindow(2000, 2008, MARCH, -29, SUNDAY, time(1, 0), false, WALL, PERIOD_1HOUR30MIN); 935 } 936 937 @Test(expectedExceptions=IllegalArgumentException.class) test_addRuleToWindow_illegalDayOfMonth_zero()938 public void test_addRuleToWindow_illegalDayOfMonth_zero() { 939 ZoneRulesBuilder b = new ZoneRulesBuilder(); 940 b.addWindowForever(OFFSET_1); 941 b.addRuleToWindow(2000, 2008, MARCH, 0, SUNDAY, time(1, 0), false, WALL, PERIOD_1HOUR30MIN); 942 } 943 944 @Test(expectedExceptions=IllegalArgumentException.class) test_addRuleToWindow_illegalDayOfMonth_tooLarge()945 public void test_addRuleToWindow_illegalDayOfMonth_tooLarge() { 946 ZoneRulesBuilder b = new ZoneRulesBuilder(); 947 b.addWindowForever(OFFSET_1); 948 b.addRuleToWindow(2000, 2008, MARCH, 32, SUNDAY, time(1, 0), false, WALL, PERIOD_1HOUR30MIN); 949 } 950 951 @Test(expectedExceptions=NullPointerException.class) test_addRuleToWindow_nullMonth()952 public void test_addRuleToWindow_nullMonth() { 953 ZoneRulesBuilder b = new ZoneRulesBuilder(); 954 b.addWindowForever(OFFSET_1); 955 b.addRuleToWindow(2000, Year.MAX_VALUE, (Month) null, 31, SUNDAY, time(1, 0), false, WALL, PERIOD_1HOUR30MIN); 956 } 957 958 @Test(expectedExceptions=NullPointerException.class) test_addRuleToWindow_nullTime()959 public void test_addRuleToWindow_nullTime() { 960 ZoneRulesBuilder b = new ZoneRulesBuilder(); 961 b.addWindowForever(OFFSET_1); 962 b.addRuleToWindow(2000, Year.MAX_VALUE, MARCH, -1, SUNDAY, (LocalTime) null, false, WALL, PERIOD_1HOUR30MIN); 963 } 964 965 @Test(expectedExceptions=IllegalArgumentException.class) test_addRuleToWindow_illegalEndOfDayTime()966 public void test_addRuleToWindow_illegalEndOfDayTime() { 967 ZoneRulesBuilder b = new ZoneRulesBuilder(); 968 b.addWindowForever(OFFSET_1); 969 b.addRuleToWindow(2000, 2008, MARCH, 1, SUNDAY, time(1, 0), true, WALL, PERIOD_1HOUR30MIN); 970 } 971 972 @Test(expectedExceptions=NullPointerException.class) test_addRuleToWindow_nullTimeDefinition()973 public void test_addRuleToWindow_nullTimeDefinition() { 974 ZoneRulesBuilder b = new ZoneRulesBuilder(); 975 b.addWindowForever(OFFSET_1); 976 b.addRuleToWindow(2000, Year.MAX_VALUE, MARCH, -1, SUNDAY, time(1, 0), false, (TimeDefinition) null, PERIOD_1HOUR30MIN); 977 } 978 979 //----------------------------------------------------------------------- 980 // addRuleToWindow() - single year object 981 //----------------------------------------------------------------------- 982 @Test test_addRuleToWindow_singleYearObject()983 public void test_addRuleToWindow_singleYearObject() { 984 ZoneRulesBuilder b = new ZoneRulesBuilder(); 985 b.addWindowForever(OFFSET_1); 986 b.addRuleToWindow(dateTime(2000, MARCH, 26, 1, 0), UTC, PERIOD_1HOUR); 987 b.addRuleToWindow(dateTime(2000, OCTOBER, 29, 1, 0), UTC, PERIOD_0); 988 ZoneRules test = b.toRules("Europe/London"); 989 assertOffsetInfo(test, dateTime(1999, 7, 1, 0, 0), OFFSET_1); 990 991 assertOffsetInfo(test, dateTime(2000, 1, 1, 0, 0), OFFSET_1); 992 assertGap(test, 2000, 3, 26, 2, 30, OFFSET_1, OFFSET_2); 993 assertOffsetInfo(test, dateTime(2000, 7, 1, 0, 0), OFFSET_2); 994 assertOverlap(test, 2000, 10, 29, 2, 30, OFFSET_2, OFFSET_1); 995 996 assertOffsetInfo(test, dateTime(2001, 7, 1, 0, 0), OFFSET_1); 997 } 998 999 @Test(expectedExceptions=NullPointerException.class) test_addRuleToWindow_singleYearObject_nullTime()1000 public void test_addRuleToWindow_singleYearObject_nullTime() { 1001 ZoneRulesBuilder b = new ZoneRulesBuilder(); 1002 b.addWindowForever(OFFSET_1); 1003 b.addRuleToWindow((LocalDateTime) null, WALL, PERIOD_1HOUR30MIN); 1004 } 1005 1006 @Test(expectedExceptions=NullPointerException.class) test_addRuleToWindow_singleYearObject_nullTimeDefinition()1007 public void test_addRuleToWindow_singleYearObject_nullTimeDefinition() { 1008 ZoneRulesBuilder b = new ZoneRulesBuilder(); 1009 b.addWindowForever(OFFSET_1); 1010 b.addRuleToWindow(dateTime(2000, MARCH, 31, 1, 0), (TimeDefinition) null, PERIOD_1HOUR30MIN); 1011 } 1012 1013 //----------------------------------------------------------------------- 1014 // addRuleToWindow() - single year 1015 //----------------------------------------------------------------------- 1016 @Test test_addRuleToWindow_singleYear()1017 public void test_addRuleToWindow_singleYear() { 1018 ZoneRulesBuilder b = new ZoneRulesBuilder(); 1019 b.addWindowForever(OFFSET_1); 1020 b.addRuleToWindow(2000, MARCH, 26, time(1, 0), false, UTC, PERIOD_1HOUR); 1021 b.addRuleToWindow(2000, OCTOBER, 29, time(1, 0), false, UTC, PERIOD_0); 1022 ZoneRules test = b.toRules("Europe/London"); 1023 assertOffsetInfo(test, dateTime(1999, 7, 1, 0, 0), OFFSET_1); 1024 1025 assertOffsetInfo(test, dateTime(2000, 1, 1, 0, 0), OFFSET_1); 1026 assertGap(test, 2000, 3, 26, 2, 30, OFFSET_1, OFFSET_2); 1027 assertOffsetInfo(test, dateTime(2000, 7, 1, 0, 0), OFFSET_2); 1028 assertOverlap(test, 2000, 10, 29, 2, 30, OFFSET_2, OFFSET_1); 1029 1030 assertOffsetInfo(test, dateTime(2001, 7, 1, 0, 0), OFFSET_1); 1031 } 1032 1033 @Test(expectedExceptions=IllegalStateException.class) test_addRuleToWindow_singleYear_noWindow()1034 public void test_addRuleToWindow_singleYear_noWindow() { 1035 ZoneRulesBuilder b = new ZoneRulesBuilder(); 1036 b.addRuleToWindow(2000, MARCH, 31, time(1, 0), false, WALL, PERIOD_1HOUR30MIN); 1037 } 1038 1039 @Test(expectedExceptions=IllegalStateException.class) test_addRuleToWindow_singleYear_cannotMixRuleWithSavings()1040 public void test_addRuleToWindow_singleYear_cannotMixRuleWithSavings() { 1041 ZoneRulesBuilder b = new ZoneRulesBuilder(); 1042 b.addWindowForever(OFFSET_1); 1043 b.setFixedSavingsToWindow(PERIOD_1HOUR30MIN); 1044 b.addRuleToWindow(2000, MARCH, 31, time(1, 0), false, WALL, PERIOD_1HOUR30MIN); 1045 } 1046 1047 @Test(expectedExceptions=DateTimeException.class) test_addRuleToWindow_singleYear_illegalYear()1048 public void test_addRuleToWindow_singleYear_illegalYear() { 1049 ZoneRulesBuilder b = new ZoneRulesBuilder(); 1050 b.addWindowForever(OFFSET_1); 1051 b.addRuleToWindow(Year.MIN_VALUE - 1, MARCH, 31, time(1, 0), false, WALL, PERIOD_1HOUR30MIN); 1052 } 1053 1054 @Test(expectedExceptions=IllegalArgumentException.class) test_addRuleToWindow_singleYear_illegalDayOfMonth_tooSmall()1055 public void test_addRuleToWindow_singleYear_illegalDayOfMonth_tooSmall() { 1056 ZoneRulesBuilder b = new ZoneRulesBuilder(); 1057 b.addWindowForever(OFFSET_1); 1058 b.addRuleToWindow(2000, MARCH, -29, time(1, 0), false, WALL, PERIOD_1HOUR30MIN); 1059 } 1060 1061 @Test(expectedExceptions=IllegalArgumentException.class) test_addRuleToWindow_singleYear_illegalDayOfMonth_zero()1062 public void test_addRuleToWindow_singleYear_illegalDayOfMonth_zero() { 1063 ZoneRulesBuilder b = new ZoneRulesBuilder(); 1064 b.addWindowForever(OFFSET_1); 1065 b.addRuleToWindow(2000, MARCH, 0, time(1, 0), false, WALL, PERIOD_1HOUR30MIN); 1066 } 1067 1068 @Test(expectedExceptions=IllegalArgumentException.class) test_addRuleToWindow_singleYear_illegalDayOfMonth_tooLarge()1069 public void test_addRuleToWindow_singleYear_illegalDayOfMonth_tooLarge() { 1070 ZoneRulesBuilder b = new ZoneRulesBuilder(); 1071 b.addWindowForever(OFFSET_1); 1072 b.addRuleToWindow(2000, MARCH, 32, time(1, 0), false, WALL, PERIOD_1HOUR30MIN); 1073 } 1074 1075 @Test(expectedExceptions=NullPointerException.class) test_addRuleToWindow_singleYear_nullMonth()1076 public void test_addRuleToWindow_singleYear_nullMonth() { 1077 ZoneRulesBuilder b = new ZoneRulesBuilder(); 1078 b.addWindowForever(OFFSET_1); 1079 b.addRuleToWindow(2000, (Month) null, 31, time(1, 0), false, WALL, PERIOD_1HOUR30MIN); 1080 } 1081 1082 @Test(expectedExceptions=NullPointerException.class) test_addRuleToWindow_singleYear_nullTime()1083 public void test_addRuleToWindow_singleYear_nullTime() { 1084 ZoneRulesBuilder b = new ZoneRulesBuilder(); 1085 b.addWindowForever(OFFSET_1); 1086 b.addRuleToWindow(2000, MARCH, 31, (LocalTime) null, false, WALL, PERIOD_1HOUR30MIN); 1087 } 1088 1089 @Test(expectedExceptions=NullPointerException.class) test_addRuleToWindow_singleYear_nullTimeDefinition()1090 public void test_addRuleToWindow_singleYear_nullTimeDefinition() { 1091 ZoneRulesBuilder b = new ZoneRulesBuilder(); 1092 b.addWindowForever(OFFSET_1); 1093 b.addRuleToWindow(2000, MARCH, 31, time(1, 0), false, (TimeDefinition) null, PERIOD_1HOUR30MIN); 1094 } 1095 1096 //----------------------------------------------------------------------- assertGap(ZoneRules test, int y, int m, int d, int hr, int min, ZoneOffset before, ZoneOffset after)1097 private static void assertGap(ZoneRules test, int y, int m, int d, int hr, int min, ZoneOffset before, ZoneOffset after) { 1098 LocalDateTime dt = dateTime(y, m, d, hr, min); 1099 ZoneOffsetTransition zot = test.getTransition(dt); 1100 assertNotNull(zot); 1101 assertEquals(zot.isGap(), true); 1102 assertEquals(zot.getOffsetBefore(), before); 1103 assertEquals(zot.getOffsetAfter(), after); 1104 } 1105 assertOverlap(ZoneRules test, int y, int m, int d, int hr, int min, ZoneOffset before, ZoneOffset after)1106 private static void assertOverlap(ZoneRules test, int y, int m, int d, int hr, int min, ZoneOffset before, ZoneOffset after) { 1107 LocalDateTime dt = dateTime(y, m, d, hr, min); 1108 ZoneOffsetTransition zot = test.getTransition(dt); 1109 assertNotNull(zot); 1110 assertEquals(zot.isOverlap(), true); 1111 assertEquals(zot.getOffsetBefore(), before); 1112 assertEquals(zot.getOffsetAfter(), after); 1113 } 1114 assertOffsetInfo(ZoneRules test, LocalDateTime dateTime, ZoneOffset offset)1115 private void assertOffsetInfo(ZoneRules test, LocalDateTime dateTime, ZoneOffset offset) { 1116 List<ZoneOffset> offsets = test.getValidOffsets(dateTime); 1117 assertEquals(offsets.size(), 1); 1118 assertEquals(offsets.get(0), offset); 1119 } 1120 1121 //----------------------------------------------------------------------- time(int h, int m)1122 private static LocalTime time(int h, int m) { 1123 return LocalTime.of(h, m); 1124 } 1125 dateTime(int year, int month, int day, int h, int m)1126 private static LocalDateTime dateTime(int year, int month, int day, int h, int m) { 1127 return LocalDateTime.of(year, month, day, h, m); 1128 } 1129 dateTime(int year, Month month, int day, int h, int m)1130 private static LocalDateTime dateTime(int year, Month month, int day, int h, int m) { 1131 return LocalDateTime.of(year, month, day, h, m); 1132 } 1133 1134 } 1135