1/* 2 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24/* 25 * This file is available under and governed by the GNU General Public 26 * License version 2 only, as published by the Free Software Foundation. 27 * However, the following notice accompanied the original version of this 28 * file: 29 * 30 * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos 31 * 32 * All rights reserved. 33 * 34 * Redistribution and use in source and binary forms, with or without 35 * modification, are permitted provided that the following conditions are met: 36 * 37 * * Redistributions of source code must retain the above copyright notice, 38 * this list of conditions and the following disclaimer. 39 * 40 * * Redistributions in binary form must reproduce the above copyright notice, 41 * this list of conditions and the following disclaimer in the documentation 42 * and/or other materials provided with the distribution. 43 * 44 * * Neither the name of JSR-310 nor the names of its contributors 45 * may be used to endorse or promote products derived from this software 46 * without specific prior written permission. 47 * 48 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 49 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 50 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 51 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 52 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 53 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 54 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 55 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 56 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 57 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 58 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 59 */ 60package tck.java.time.zone; 61 62import static org.testng.Assert.assertEquals; 63import static org.testng.Assert.assertFalse; 64import static org.testng.Assert.assertNotNull; 65import static org.testng.Assert.assertTrue; 66 67import java.io.ByteArrayInputStream; 68import java.io.ByteArrayOutputStream; 69import java.io.ObjectInputStream; 70import java.io.ObjectOutputStream; 71import java.time.DayOfWeek; 72import java.time.Duration; 73import java.time.Instant; 74import java.time.LocalDate; 75import java.time.LocalDateTime; 76import java.time.LocalTime; 77import java.time.Month; 78import java.time.OffsetDateTime; 79import java.time.Year; 80import java.time.ZoneId; 81import java.time.ZoneOffset; 82import java.time.ZonedDateTime; 83import java.time.zone.ZoneOffsetTransition; 84import java.time.zone.ZoneOffsetTransitionRule; 85import java.time.zone.ZoneOffsetTransitionRule.TimeDefinition; 86import java.time.zone.ZoneRules; 87import java.util.ArrayList; 88import java.util.Iterator; 89import java.util.List; 90 91import org.testng.annotations.Test; 92 93/** 94 * Test ZoneRules. 95 */ 96@Test 97public class TCKZoneRules { 98 99 private static final ZoneOffset OFFSET_ZERO = ZoneOffset.ofHours(0); 100 private static final ZoneOffset OFFSET_PONE = ZoneOffset.ofHours(1); 101 private static final ZoneOffset OFFSET_PTWO = ZoneOffset.ofHours(2); 102 public static final String LATEST_TZDB = "2009b"; 103 private static final int OVERLAP = 2; 104 private static final int GAP = 0; 105 106 107 108 //----------------------------------------------------------------------- 109 // Europe/London 110 //----------------------------------------------------------------------- 111 private ZoneRules europeLondon() { 112 return ZoneId.of("Europe/London").getRules(); 113 } 114 115 public void test_London() { 116 ZoneRules test = europeLondon(); 117 assertEquals(test.isFixedOffset(), false); 118 } 119 120 public void test_London_preTimeZones() { 121 ZoneRules test = europeLondon(); 122 ZonedDateTime old = createZDT(1800, 1, 1, ZoneOffset.UTC); 123 Instant instant = old.toInstant(); 124 ZoneOffset offset = ZoneOffset.ofHoursMinutesSeconds(0, -1, -15); 125 assertEquals(test.getOffset(instant), offset); 126 checkOffset(test, old.toLocalDateTime(), offset, 1); 127 assertEquals(test.getStandardOffset(instant), offset); 128 assertEquals(test.getDaylightSavings(instant), Duration.ZERO); 129 assertEquals(test.isDaylightSavings(instant), false); 130 } 131 132 public void test_London_getOffset() { 133 ZoneRules test = europeLondon(); 134 assertEquals(test.getOffset(createInstant(2008, 1, 1, ZoneOffset.UTC)), OFFSET_ZERO); 135 assertEquals(test.getOffset(createInstant(2008, 2, 1, ZoneOffset.UTC)), OFFSET_ZERO); 136 assertEquals(test.getOffset(createInstant(2008, 3, 1, ZoneOffset.UTC)), OFFSET_ZERO); 137 assertEquals(test.getOffset(createInstant(2008, 4, 1, ZoneOffset.UTC)), OFFSET_PONE); 138 assertEquals(test.getOffset(createInstant(2008, 5, 1, ZoneOffset.UTC)), OFFSET_PONE); 139 assertEquals(test.getOffset(createInstant(2008, 6, 1, ZoneOffset.UTC)), OFFSET_PONE); 140 assertEquals(test.getOffset(createInstant(2008, 7, 1, ZoneOffset.UTC)), OFFSET_PONE); 141 assertEquals(test.getOffset(createInstant(2008, 8, 1, ZoneOffset.UTC)), OFFSET_PONE); 142 assertEquals(test.getOffset(createInstant(2008, 9, 1, ZoneOffset.UTC)), OFFSET_PONE); 143 assertEquals(test.getOffset(createInstant(2008, 10, 1, ZoneOffset.UTC)), OFFSET_PONE); 144 assertEquals(test.getOffset(createInstant(2008, 11, 1, ZoneOffset.UTC)), OFFSET_ZERO); 145 assertEquals(test.getOffset(createInstant(2008, 12, 1, ZoneOffset.UTC)), OFFSET_ZERO); 146 } 147 148 public void test_London_getOffset_toDST() { 149 ZoneRules test = europeLondon(); 150 assertEquals(test.getOffset(createInstant(2008, 3, 24, ZoneOffset.UTC)), OFFSET_ZERO); 151 assertEquals(test.getOffset(createInstant(2008, 3, 25, ZoneOffset.UTC)), OFFSET_ZERO); 152 assertEquals(test.getOffset(createInstant(2008, 3, 26, ZoneOffset.UTC)), OFFSET_ZERO); 153 assertEquals(test.getOffset(createInstant(2008, 3, 27, ZoneOffset.UTC)), OFFSET_ZERO); 154 assertEquals(test.getOffset(createInstant(2008, 3, 28, ZoneOffset.UTC)), OFFSET_ZERO); 155 assertEquals(test.getOffset(createInstant(2008, 3, 29, ZoneOffset.UTC)), OFFSET_ZERO); 156 assertEquals(test.getOffset(createInstant(2008, 3, 30, ZoneOffset.UTC)), OFFSET_ZERO); 157 assertEquals(test.getOffset(createInstant(2008, 3, 31, ZoneOffset.UTC)), OFFSET_PONE); 158 // cutover at 01:00Z 159 assertEquals(test.getOffset(createInstant(2008, 3, 30, 0, 59, 59, 999999999, ZoneOffset.UTC)), OFFSET_ZERO); 160 assertEquals(test.getOffset(createInstant(2008, 3, 30, 1, 0, 0, 0, ZoneOffset.UTC)), OFFSET_PONE); 161 } 162 163 public void test_London_getOffset_fromDST() { 164 ZoneRules test = europeLondon(); 165 assertEquals(test.getOffset(createInstant(2008, 10, 24, ZoneOffset.UTC)), OFFSET_PONE); 166 assertEquals(test.getOffset(createInstant(2008, 10, 25, ZoneOffset.UTC)), OFFSET_PONE); 167 assertEquals(test.getOffset(createInstant(2008, 10, 26, ZoneOffset.UTC)), OFFSET_PONE); 168 assertEquals(test.getOffset(createInstant(2008, 10, 27, ZoneOffset.UTC)), OFFSET_ZERO); 169 assertEquals(test.getOffset(createInstant(2008, 10, 28, ZoneOffset.UTC)), OFFSET_ZERO); 170 assertEquals(test.getOffset(createInstant(2008, 10, 29, ZoneOffset.UTC)), OFFSET_ZERO); 171 assertEquals(test.getOffset(createInstant(2008, 10, 30, ZoneOffset.UTC)), OFFSET_ZERO); 172 assertEquals(test.getOffset(createInstant(2008, 10, 31, ZoneOffset.UTC)), OFFSET_ZERO); 173 // cutover at 01:00Z 174 assertEquals(test.getOffset(createInstant(2008, 10, 26, 0, 59, 59, 999999999, ZoneOffset.UTC)), OFFSET_PONE); 175 assertEquals(test.getOffset(createInstant(2008, 10, 26, 1, 0, 0, 0, ZoneOffset.UTC)), OFFSET_ZERO); 176 } 177 178 public void test_London_getOffsetInfo() { 179 ZoneRules test = europeLondon(); 180 checkOffset(test, createLDT(2008, 1, 1), OFFSET_ZERO, 1); 181 checkOffset(test, createLDT(2008, 2, 1), OFFSET_ZERO, 1); 182 checkOffset(test, createLDT(2008, 3, 1), OFFSET_ZERO, 1); 183 checkOffset(test, createLDT(2008, 4, 1), OFFSET_PONE, 1); 184 checkOffset(test, createLDT(2008, 5, 1), OFFSET_PONE, 1); 185 checkOffset(test, createLDT(2008, 6, 1), OFFSET_PONE, 1); 186 checkOffset(test, createLDT(2008, 7, 1), OFFSET_PONE, 1); 187 checkOffset(test, createLDT(2008, 8, 1), OFFSET_PONE, 1); 188 checkOffset(test, createLDT(2008, 9, 1), OFFSET_PONE, 1); 189 checkOffset(test, createLDT(2008, 10, 1), OFFSET_PONE, 1); 190 checkOffset(test, createLDT(2008, 11, 1), OFFSET_ZERO, 1); 191 checkOffset(test, createLDT(2008, 12, 1), OFFSET_ZERO, 1); 192 } 193 194 public void test_London_getOffsetInfo_toDST() { 195 ZoneRules test = europeLondon(); 196 checkOffset(test, createLDT(2008, 3, 24), OFFSET_ZERO, 1); 197 checkOffset(test, createLDT(2008, 3, 25), OFFSET_ZERO, 1); 198 checkOffset(test, createLDT(2008, 3, 26), OFFSET_ZERO, 1); 199 checkOffset(test, createLDT(2008, 3, 27), OFFSET_ZERO, 1); 200 checkOffset(test, createLDT(2008, 3, 28), OFFSET_ZERO, 1); 201 checkOffset(test, createLDT(2008, 3, 29), OFFSET_ZERO, 1); 202 checkOffset(test, createLDT(2008, 3, 30), OFFSET_ZERO, 1); 203 checkOffset(test, createLDT(2008, 3, 31), OFFSET_PONE, 1); 204 // cutover at 01:00Z 205 checkOffset(test, LocalDateTime.of(2008, 3, 30, 0, 59, 59, 999999999), OFFSET_ZERO, 1); 206 checkOffset(test, LocalDateTime.of(2008, 3, 30, 2, 0, 0, 0), OFFSET_PONE, 1); 207 } 208 209 public void test_London_getOffsetInfo_fromDST() { 210 ZoneRules test = europeLondon(); 211 checkOffset(test, createLDT(2008, 10, 24), OFFSET_PONE, 1); 212 checkOffset(test, createLDT(2008, 10, 25), OFFSET_PONE, 1); 213 checkOffset(test, createLDT(2008, 10, 26), OFFSET_PONE, 1); 214 checkOffset(test, createLDT(2008, 10, 27), OFFSET_ZERO, 1); 215 checkOffset(test, createLDT(2008, 10, 28), OFFSET_ZERO, 1); 216 checkOffset(test, createLDT(2008, 10, 29), OFFSET_ZERO, 1); 217 checkOffset(test, createLDT(2008, 10, 30), OFFSET_ZERO, 1); 218 checkOffset(test, createLDT(2008, 10, 31), OFFSET_ZERO, 1); 219 // cutover at 01:00Z 220 checkOffset(test, LocalDateTime.of(2008, 10, 26, 0, 59, 59, 999999999), OFFSET_PONE, 1); 221 checkOffset(test, LocalDateTime.of(2008, 10, 26, 2, 0, 0, 0), OFFSET_ZERO, 1); 222 } 223 224 public void test_London_getOffsetInfo_gap() { 225 ZoneRules test = europeLondon(); 226 final LocalDateTime dateTime = LocalDateTime.of(2008, 3, 30, 1, 0, 0, 0); 227 ZoneOffsetTransition trans = checkOffset(test, dateTime, OFFSET_ZERO, GAP); 228 assertEquals(trans.isGap(), true); 229 assertEquals(trans.isOverlap(), false); 230 assertEquals(trans.getOffsetBefore(), OFFSET_ZERO); 231 assertEquals(trans.getOffsetAfter(), OFFSET_PONE); 232 assertEquals(trans.getInstant(), createInstant(2008, 3, 30, 1, 0, ZoneOffset.UTC)); 233 assertEquals(trans.getDateTimeBefore(), LocalDateTime.of(2008, 3, 30, 1, 0)); 234 assertEquals(trans.getDateTimeAfter(), LocalDateTime.of(2008, 3, 30, 2, 0)); 235 assertEquals(trans.isValidOffset(OFFSET_ZERO), false); 236 assertEquals(trans.isValidOffset(OFFSET_PONE), false); 237 assertEquals(trans.isValidOffset(OFFSET_PTWO), false); 238 assertEquals(trans.toString(), "Transition[Gap at 2008-03-30T01:00Z to +01:00]"); 239 240 assertFalse(trans.equals(null)); 241 assertFalse(trans.equals(OFFSET_ZERO)); 242 assertTrue(trans.equals(trans)); 243 244 final ZoneOffsetTransition otherTrans = test.getTransition(dateTime); 245 assertTrue(trans.equals(otherTrans)); 246 assertEquals(trans.hashCode(), otherTrans.hashCode()); 247 } 248 249 public void test_London_getOffsetInfo_overlap() { 250 ZoneRules test = europeLondon(); 251 final LocalDateTime dateTime = LocalDateTime.of(2008, 10, 26, 1, 0, 0, 0); 252 ZoneOffsetTransition trans = checkOffset(test, dateTime, OFFSET_PONE, OVERLAP); 253 assertEquals(trans.isGap(), false); 254 assertEquals(trans.isOverlap(), true); 255 assertEquals(trans.getOffsetBefore(), OFFSET_PONE); 256 assertEquals(trans.getOffsetAfter(), OFFSET_ZERO); 257 assertEquals(trans.getInstant(), createInstant(2008, 10, 26, 1, 0, ZoneOffset.UTC)); 258 assertEquals(trans.getDateTimeBefore(), LocalDateTime.of(2008, 10, 26, 2, 0)); 259 assertEquals(trans.getDateTimeAfter(), LocalDateTime.of(2008, 10, 26, 1, 0)); 260 assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-1)), false); 261 assertEquals(trans.isValidOffset(OFFSET_ZERO), true); 262 assertEquals(trans.isValidOffset(OFFSET_PONE), true); 263 assertEquals(trans.isValidOffset(OFFSET_PTWO), false); 264 assertEquals(trans.toString(), "Transition[Overlap at 2008-10-26T02:00+01:00 to Z]"); 265 266 assertFalse(trans.equals(null)); 267 assertFalse(trans.equals(OFFSET_PONE)); 268 assertTrue(trans.equals(trans)); 269 270 final ZoneOffsetTransition otherTrans = test.getTransition(dateTime); 271 assertTrue(trans.equals(otherTrans)); 272 assertEquals(trans.hashCode(), otherTrans.hashCode()); 273 } 274 275 public void test_London_getStandardOffset() { 276 ZoneRules test = europeLondon(); 277 ZonedDateTime zdt = createZDT(1840, 1, 1, ZoneOffset.UTC); 278 while (zdt.getYear() < 2010) { 279 Instant instant = zdt.toInstant(); 280 if (zdt.getYear() < 1848) { 281 assertEquals(test.getStandardOffset(instant), ZoneOffset.ofHoursMinutesSeconds(0, -1, -15)); 282 } else if (zdt.getYear() >= 1969 && zdt.getYear() < 1972) { 283 assertEquals(test.getStandardOffset(instant), OFFSET_PONE); 284 } else { 285 assertEquals(test.getStandardOffset(instant), OFFSET_ZERO); 286 } 287 zdt = zdt.plusMonths(6); 288 } 289 } 290 291 public void test_London_getTransitions() { 292 ZoneRules test = europeLondon(); 293 List<ZoneOffsetTransition> trans = test.getTransitions(); 294 295 ZoneOffsetTransition first = trans.get(0); 296 assertEquals(first.getDateTimeBefore(), LocalDateTime.of(1847, 12, 1, 0, 0)); 297 assertEquals(first.getOffsetBefore(), ZoneOffset.ofHoursMinutesSeconds(0, -1, -15)); 298 assertEquals(first.getOffsetAfter(), OFFSET_ZERO); 299 300 ZoneOffsetTransition spring1916 = trans.get(1); 301 assertEquals(spring1916.getDateTimeBefore(), LocalDateTime.of(1916, 5, 21, 2, 0)); 302 assertEquals(spring1916.getOffsetBefore(), OFFSET_ZERO); 303 assertEquals(spring1916.getOffsetAfter(), OFFSET_PONE); 304 305 ZoneOffsetTransition autumn1916 = trans.get(2); 306 assertEquals(autumn1916.getDateTimeBefore(), LocalDateTime.of(1916, 10, 1, 3, 0)); 307 assertEquals(autumn1916.getOffsetBefore(), OFFSET_PONE); 308 assertEquals(autumn1916.getOffsetAfter(), OFFSET_ZERO); 309 310 ZoneOffsetTransition zot = null; 311 Iterator<ZoneOffsetTransition> it = trans.iterator(); 312 while (it.hasNext()) { 313 zot = it.next(); 314 if (zot.getDateTimeBefore().getYear() == 1990) { 315 break; 316 } 317 } 318 assertEquals(zot.getDateTimeBefore(), LocalDateTime.of(1990, 3, 25, 1, 0)); 319 assertEquals(zot.getOffsetBefore(), OFFSET_ZERO); 320 zot = it.next(); 321 assertEquals(zot.getDateTimeBefore(), LocalDateTime.of(1990, 10, 28, 2, 0)); 322 assertEquals(zot.getOffsetBefore(), OFFSET_PONE); 323 zot = it.next(); 324 assertEquals(zot.getDateTimeBefore(), LocalDateTime.of(1991, 3, 31, 1, 0)); 325 assertEquals(zot.getOffsetBefore(), OFFSET_ZERO); 326 zot = it.next(); 327 assertEquals(zot.getDateTimeBefore(), LocalDateTime.of(1991, 10, 27, 2, 0)); 328 assertEquals(zot.getOffsetBefore(), OFFSET_PONE); 329 zot = it.next(); 330 assertEquals(zot.getDateTimeBefore(), LocalDateTime.of(1992, 3, 29, 1, 0)); 331 assertEquals(zot.getOffsetBefore(), OFFSET_ZERO); 332 zot = it.next(); 333 assertEquals(zot.getDateTimeBefore(), LocalDateTime.of(1992, 10, 25, 2, 0)); 334 assertEquals(zot.getOffsetBefore(), OFFSET_PONE); 335 zot = it.next(); 336 assertEquals(zot.getDateTimeBefore(), LocalDateTime.of(1993, 3, 28, 1, 0)); 337 assertEquals(zot.getOffsetBefore(), OFFSET_ZERO); 338 zot = it.next(); 339 assertEquals(zot.getDateTimeBefore(), LocalDateTime.of(1993, 10, 24, 2, 0)); 340 assertEquals(zot.getOffsetBefore(), OFFSET_PONE); 341 zot = it.next(); 342 assertEquals(zot.getDateTimeBefore(), LocalDateTime.of(1994, 3, 27, 1, 0)); 343 assertEquals(zot.getOffsetBefore(), OFFSET_ZERO); 344 zot = it.next(); 345 assertEquals(zot.getDateTimeBefore(), LocalDateTime.of(1994, 10, 23, 2, 0)); 346 assertEquals(zot.getOffsetBefore(), OFFSET_PONE); 347 zot = it.next(); 348 assertEquals(zot.getDateTimeBefore(), LocalDateTime.of(1995, 3, 26, 1, 0)); 349 assertEquals(zot.getOffsetBefore(), OFFSET_ZERO); 350 zot = it.next(); 351 assertEquals(zot.getDateTimeBefore(), LocalDateTime.of(1995, 10, 22, 2, 0)); 352 assertEquals(zot.getOffsetBefore(), OFFSET_PONE); 353 zot = it.next(); 354 assertEquals(zot.getDateTimeBefore(), LocalDateTime.of(1996, 3, 31, 1, 0)); 355 assertEquals(zot.getOffsetBefore(), OFFSET_ZERO); 356 zot = it.next(); 357 assertEquals(zot.getDateTimeBefore(), LocalDateTime.of(1996, 10, 27, 2, 0)); 358 assertEquals(zot.getOffsetBefore(), OFFSET_PONE); 359 zot = it.next(); 360 assertEquals(zot.getDateTimeBefore(), LocalDateTime.of(1997, 3, 30, 1, 0)); 361 assertEquals(zot.getOffsetBefore(), OFFSET_ZERO); 362 zot = it.next(); 363 assertEquals(zot.getDateTimeBefore(), LocalDateTime.of(1997, 10, 26, 2, 0)); 364 assertEquals(zot.getOffsetBefore(), OFFSET_PONE); 365 assertEquals(it.hasNext(), false); 366 } 367 368 public void test_London_getTransitionRules() { 369 ZoneRules test = europeLondon(); 370 List<ZoneOffsetTransitionRule> rules = test.getTransitionRules(); 371 assertEquals(rules.size(), 2); 372 373 ZoneOffsetTransitionRule in = rules.get(0); 374 assertEquals(in.getMonth(), Month.MARCH); 375 assertEquals(in.getDayOfMonthIndicator(), 25); // optimized from -1 376 assertEquals(in.getDayOfWeek(), DayOfWeek.SUNDAY); 377 assertEquals(in.getLocalTime(), LocalTime.of(1, 0)); 378 assertEquals(in.getTimeDefinition(), TimeDefinition.UTC); 379 assertEquals(in.getStandardOffset(), OFFSET_ZERO); 380 assertEquals(in.getOffsetBefore(), OFFSET_ZERO); 381 assertEquals(in.getOffsetAfter(), OFFSET_PONE); 382 383 ZoneOffsetTransitionRule out = rules.get(1); 384 assertEquals(out.getMonth(), Month.OCTOBER); 385 assertEquals(out.getDayOfMonthIndicator(), 25); // optimized from -1 386 assertEquals(out.getDayOfWeek(), DayOfWeek.SUNDAY); 387 assertEquals(out.getLocalTime(), LocalTime.of(1, 0)); 388 assertEquals(out.getTimeDefinition(), TimeDefinition.UTC); 389 assertEquals(out.getStandardOffset(), OFFSET_ZERO); 390 assertEquals(out.getOffsetBefore(), OFFSET_PONE); 391 assertEquals(out.getOffsetAfter(), OFFSET_ZERO); 392 } 393 394 //----------------------------------------------------------------------- 395 public void test_London_nextTransition_historic() { 396 ZoneRules test = europeLondon(); 397 List<ZoneOffsetTransition> trans = test.getTransitions(); 398 399 ZoneOffsetTransition first = trans.get(0); 400 assertEquals(test.nextTransition(first.getInstant().minusNanos(1)), first); 401 402 for (int i = 0; i < trans.size() - 1; i++) { 403 ZoneOffsetTransition cur = trans.get(i); 404 ZoneOffsetTransition next = trans.get(i + 1); 405 406 assertEquals(test.nextTransition(cur.getInstant()), next); 407 assertEquals(test.nextTransition(next.getInstant().minusNanos(1)), next); 408 } 409 } 410 411 public void test_London_nextTransition_rulesBased() { 412 ZoneRules test = europeLondon(); 413 List<ZoneOffsetTransitionRule> rules = test.getTransitionRules(); 414 List<ZoneOffsetTransition> trans = test.getTransitions(); 415 416 ZoneOffsetTransition last = trans.get(trans.size() - 1); 417 assertEquals(test.nextTransition(last.getInstant()), rules.get(0).createTransition(1998)); 418 419 for (int year = 1998; year < 2010; year++) { 420 ZoneOffsetTransition a = rules.get(0).createTransition(year); 421 ZoneOffsetTransition b = rules.get(1).createTransition(year); 422 ZoneOffsetTransition c = rules.get(0).createTransition(year + 1); 423 424 assertEquals(test.nextTransition(a.getInstant()), b); 425 assertEquals(test.nextTransition(b.getInstant().minusNanos(1)), b); 426 427 assertEquals(test.nextTransition(b.getInstant()), c); 428 assertEquals(test.nextTransition(c.getInstant().minusNanos(1)), c); 429 } 430 } 431 432 public void test_London_nextTransition_lastYear() { 433 ZoneRules test = europeLondon(); 434 List<ZoneOffsetTransitionRule> rules = test.getTransitionRules(); 435 ZoneOffsetTransition zot = rules.get(1).createTransition(Year.MAX_VALUE); 436 assertEquals(test.nextTransition(zot.getInstant()), null); 437 } 438 439 //----------------------------------------------------------------------- 440 public void test_London_previousTransition_historic() { 441 ZoneRules test = europeLondon(); 442 List<ZoneOffsetTransition> trans = test.getTransitions(); 443 444 ZoneOffsetTransition first = trans.get(0); 445 assertEquals(test.previousTransition(first.getInstant()), null); 446 assertEquals(test.previousTransition(first.getInstant().minusNanos(1)), null); 447 448 for (int i = 0; i < trans.size() - 1; i++) { 449 ZoneOffsetTransition prev = trans.get(i); 450 ZoneOffsetTransition cur = trans.get(i + 1); 451 452 assertEquals(test.previousTransition(cur.getInstant()), prev); 453 assertEquals(test.previousTransition(prev.getInstant().plusSeconds(1)), prev); 454 assertEquals(test.previousTransition(prev.getInstant().plusNanos(1)), prev); 455 } 456 } 457 458 public void test_London_previousTransition_rulesBased() { 459 ZoneRules test = europeLondon(); 460 List<ZoneOffsetTransitionRule> rules = test.getTransitionRules(); 461 List<ZoneOffsetTransition> trans = test.getTransitions(); 462 463 ZoneOffsetTransition last = trans.get(trans.size() - 1); 464 assertEquals(test.previousTransition(last.getInstant().plusSeconds(1)), last); 465 assertEquals(test.previousTransition(last.getInstant().plusNanos(1)), last); 466 467 // Jan 1st of year between transitions and rules 468 ZonedDateTime odt = ZonedDateTime.ofInstant(last.getInstant(), last.getOffsetAfter()); 469 odt = odt.withDayOfYear(1).plusYears(1).with(LocalTime.MIDNIGHT); 470 assertEquals(test.previousTransition(odt.toInstant()), last); 471 472 // later years 473 for (int year = 1998; year < 2010; year++) { 474 ZoneOffsetTransition a = rules.get(0).createTransition(year); 475 ZoneOffsetTransition b = rules.get(1).createTransition(year); 476 ZoneOffsetTransition c = rules.get(0).createTransition(year + 1); 477 478 assertEquals(test.previousTransition(c.getInstant()), b); 479 assertEquals(test.previousTransition(b.getInstant().plusSeconds(1)), b); 480 assertEquals(test.previousTransition(b.getInstant().plusNanos(1)), b); 481 482 assertEquals(test.previousTransition(b.getInstant()), a); 483 assertEquals(test.previousTransition(a.getInstant().plusSeconds(1)), a); 484 assertEquals(test.previousTransition(a.getInstant().plusNanos(1)), a); 485 } 486 } 487 488 //----------------------------------------------------------------------- 489 // Europe/Paris 490 //----------------------------------------------------------------------- 491 private ZoneRules europeParis() { 492 return ZoneId.of("Europe/Paris").getRules(); 493 } 494 495 public void test_Paris() { 496 ZoneRules test = europeParis(); 497 assertEquals(test.isFixedOffset(), false); 498 } 499 500 public void test_Paris_preTimeZones() { 501 ZoneRules test = europeParis(); 502 ZonedDateTime old = createZDT(1800, 1, 1, ZoneOffset.UTC); 503 Instant instant = old.toInstant(); 504 ZoneOffset offset = ZoneOffset.ofHoursMinutesSeconds(0, 9, 21); 505 assertEquals(test.getOffset(instant), offset); 506 checkOffset(test, old.toLocalDateTime(), offset, 1); 507 assertEquals(test.getStandardOffset(instant), offset); 508 assertEquals(test.getDaylightSavings(instant), Duration.ZERO); 509 assertEquals(test.isDaylightSavings(instant), false); 510 } 511 512 public void test_Paris_getOffset() { 513 ZoneRules test = europeParis(); 514 assertEquals(test.getOffset(createInstant(2008, 1, 1, ZoneOffset.UTC)), OFFSET_PONE); 515 assertEquals(test.getOffset(createInstant(2008, 2, 1, ZoneOffset.UTC)), OFFSET_PONE); 516 assertEquals(test.getOffset(createInstant(2008, 3, 1, ZoneOffset.UTC)), OFFSET_PONE); 517 assertEquals(test.getOffset(createInstant(2008, 4, 1, ZoneOffset.UTC)), OFFSET_PTWO); 518 assertEquals(test.getOffset(createInstant(2008, 5, 1, ZoneOffset.UTC)), OFFSET_PTWO); 519 assertEquals(test.getOffset(createInstant(2008, 6, 1, ZoneOffset.UTC)), OFFSET_PTWO); 520 assertEquals(test.getOffset(createInstant(2008, 7, 1, ZoneOffset.UTC)), OFFSET_PTWO); 521 assertEquals(test.getOffset(createInstant(2008, 8, 1, ZoneOffset.UTC)), OFFSET_PTWO); 522 assertEquals(test.getOffset(createInstant(2008, 9, 1, ZoneOffset.UTC)), OFFSET_PTWO); 523 assertEquals(test.getOffset(createInstant(2008, 10, 1, ZoneOffset.UTC)), OFFSET_PTWO); 524 assertEquals(test.getOffset(createInstant(2008, 11, 1, ZoneOffset.UTC)), OFFSET_PONE); 525 assertEquals(test.getOffset(createInstant(2008, 12, 1, ZoneOffset.UTC)), OFFSET_PONE); 526 } 527 528 public void test_Paris_getOffset_toDST() { 529 ZoneRules test = europeParis(); 530 assertEquals(test.getOffset(createInstant(2008, 3, 24, ZoneOffset.UTC)), OFFSET_PONE); 531 assertEquals(test.getOffset(createInstant(2008, 3, 25, ZoneOffset.UTC)), OFFSET_PONE); 532 assertEquals(test.getOffset(createInstant(2008, 3, 26, ZoneOffset.UTC)), OFFSET_PONE); 533 assertEquals(test.getOffset(createInstant(2008, 3, 27, ZoneOffset.UTC)), OFFSET_PONE); 534 assertEquals(test.getOffset(createInstant(2008, 3, 28, ZoneOffset.UTC)), OFFSET_PONE); 535 assertEquals(test.getOffset(createInstant(2008, 3, 29, ZoneOffset.UTC)), OFFSET_PONE); 536 assertEquals(test.getOffset(createInstant(2008, 3, 30, ZoneOffset.UTC)), OFFSET_PONE); 537 assertEquals(test.getOffset(createInstant(2008, 3, 31, ZoneOffset.UTC)), OFFSET_PTWO); 538 // cutover at 01:00Z 539 assertEquals(test.getOffset(createInstant(2008, 3, 30, 0, 59, 59, 999999999, ZoneOffset.UTC)), OFFSET_PONE); 540 assertEquals(test.getOffset(createInstant(2008, 3, 30, 1, 0, 0, 0, ZoneOffset.UTC)), OFFSET_PTWO); 541 } 542 543 public void test_Paris_getOffset_fromDST() { 544 ZoneRules test = europeParis(); 545 assertEquals(test.getOffset(createInstant(2008, 10, 24, ZoneOffset.UTC)), OFFSET_PTWO); 546 assertEquals(test.getOffset(createInstant(2008, 10, 25, ZoneOffset.UTC)), OFFSET_PTWO); 547 assertEquals(test.getOffset(createInstant(2008, 10, 26, ZoneOffset.UTC)), OFFSET_PTWO); 548 assertEquals(test.getOffset(createInstant(2008, 10, 27, ZoneOffset.UTC)), OFFSET_PONE); 549 assertEquals(test.getOffset(createInstant(2008, 10, 28, ZoneOffset.UTC)), OFFSET_PONE); 550 assertEquals(test.getOffset(createInstant(2008, 10, 29, ZoneOffset.UTC)), OFFSET_PONE); 551 assertEquals(test.getOffset(createInstant(2008, 10, 30, ZoneOffset.UTC)), OFFSET_PONE); 552 assertEquals(test.getOffset(createInstant(2008, 10, 31, ZoneOffset.UTC)), OFFSET_PONE); 553 // cutover at 01:00Z 554 assertEquals(test.getOffset(createInstant(2008, 10, 26, 0, 59, 59, 999999999, ZoneOffset.UTC)), OFFSET_PTWO); 555 assertEquals(test.getOffset(createInstant(2008, 10, 26, 1, 0, 0, 0, ZoneOffset.UTC)), OFFSET_PONE); 556 } 557 558 public void test_Paris_getOffsetInfo() { 559 ZoneRules test = europeParis(); 560 checkOffset(test, createLDT(2008, 1, 1), OFFSET_PONE, 1); 561 checkOffset(test, createLDT(2008, 2, 1), OFFSET_PONE, 1); 562 checkOffset(test, createLDT(2008, 3, 1), OFFSET_PONE, 1); 563 checkOffset(test, createLDT(2008, 4, 1), OFFSET_PTWO, 1); 564 checkOffset(test, createLDT(2008, 5, 1), OFFSET_PTWO, 1); 565 checkOffset(test, createLDT(2008, 6, 1), OFFSET_PTWO, 1); 566 checkOffset(test, createLDT(2008, 7, 1), OFFSET_PTWO, 1); 567 checkOffset(test, createLDT(2008, 8, 1), OFFSET_PTWO, 1); 568 checkOffset(test, createLDT(2008, 9, 1), OFFSET_PTWO, 1); 569 checkOffset(test, createLDT(2008, 10, 1), OFFSET_PTWO, 1); 570 checkOffset(test, createLDT(2008, 11, 1), OFFSET_PONE, 1); 571 checkOffset(test, createLDT(2008, 12, 1), OFFSET_PONE, 1); 572 } 573 574 public void test_Paris_getOffsetInfo_toDST() { 575 ZoneRules test = europeParis(); 576 checkOffset(test, createLDT(2008, 3, 24), OFFSET_PONE, 1); 577 checkOffset(test, createLDT(2008, 3, 25), OFFSET_PONE, 1); 578 checkOffset(test, createLDT(2008, 3, 26), OFFSET_PONE, 1); 579 checkOffset(test, createLDT(2008, 3, 27), OFFSET_PONE, 1); 580 checkOffset(test, createLDT(2008, 3, 28), OFFSET_PONE, 1); 581 checkOffset(test, createLDT(2008, 3, 29), OFFSET_PONE, 1); 582 checkOffset(test, createLDT(2008, 3, 30), OFFSET_PONE, 1); 583 checkOffset(test, createLDT(2008, 3, 31), OFFSET_PTWO, 1); 584 // cutover at 01:00Z which is 02:00+01:00(local Paris time) 585 checkOffset(test, LocalDateTime.of(2008, 3, 30, 1, 59, 59, 999999999), OFFSET_PONE, 1); 586 checkOffset(test, LocalDateTime.of(2008, 3, 30, 3, 0, 0, 0), OFFSET_PTWO, 1); 587 } 588 589 public void test_Paris_getOffsetInfo_fromDST() { 590 ZoneRules test = europeParis(); 591 checkOffset(test, createLDT(2008, 10, 24), OFFSET_PTWO, 1); 592 checkOffset(test, createLDT(2008, 10, 25), OFFSET_PTWO, 1); 593 checkOffset(test, createLDT(2008, 10, 26), OFFSET_PTWO, 1); 594 checkOffset(test, createLDT(2008, 10, 27), OFFSET_PONE, 1); 595 checkOffset(test, createLDT(2008, 10, 28), OFFSET_PONE, 1); 596 checkOffset(test, createLDT(2008, 10, 29), OFFSET_PONE, 1); 597 checkOffset(test, createLDT(2008, 10, 30), OFFSET_PONE, 1); 598 checkOffset(test, createLDT(2008, 10, 31), OFFSET_PONE, 1); 599 // cutover at 01:00Z which is 02:00+01:00(local Paris time) 600 checkOffset(test, LocalDateTime.of(2008, 10, 26, 1, 59, 59, 999999999), OFFSET_PTWO, 1); 601 checkOffset(test, LocalDateTime.of(2008, 10, 26, 3, 0, 0, 0), OFFSET_PONE, 1); 602 } 603 604 public void test_Paris_getOffsetInfo_gap() { 605 ZoneRules test = europeParis(); 606 final LocalDateTime dateTime = LocalDateTime.of(2008, 3, 30, 2, 0, 0, 0); 607 ZoneOffsetTransition trans = checkOffset(test, dateTime, OFFSET_PONE, GAP); 608 assertEquals(trans.isGap(), true); 609 assertEquals(trans.isOverlap(), false); 610 assertEquals(trans.getOffsetBefore(), OFFSET_PONE); 611 assertEquals(trans.getOffsetAfter(), OFFSET_PTWO); 612 assertEquals(trans.getInstant(), createInstant(2008, 3, 30, 1, 0, ZoneOffset.UTC)); 613 assertEquals(trans.isValidOffset(OFFSET_ZERO), false); 614 assertEquals(trans.isValidOffset(OFFSET_PONE), false); 615 assertEquals(trans.isValidOffset(OFFSET_PTWO), false); 616 assertEquals(trans.toString(), "Transition[Gap at 2008-03-30T02:00+01:00 to +02:00]"); 617 618 assertFalse(trans.equals(null)); 619 assertFalse(trans.equals(OFFSET_PONE)); 620 assertTrue(trans.equals(trans)); 621 622 final ZoneOffsetTransition otherTrans = test.getTransition(dateTime); 623 assertTrue(trans.equals(otherTrans)); 624 assertEquals(trans.hashCode(), otherTrans.hashCode()); 625 } 626 627 public void test_Paris_getOffsetInfo_overlap() { 628 ZoneRules test = europeParis(); 629 final LocalDateTime dateTime = LocalDateTime.of(2008, 10, 26, 2, 0, 0, 0); 630 ZoneOffsetTransition trans = checkOffset(test, dateTime, OFFSET_PTWO, OVERLAP); 631 assertEquals(trans.isGap(), false); 632 assertEquals(trans.isOverlap(), true); 633 assertEquals(trans.getOffsetBefore(), OFFSET_PTWO); 634 assertEquals(trans.getOffsetAfter(), OFFSET_PONE); 635 assertEquals(trans.getInstant(), createInstant(2008, 10, 26, 1, 0, ZoneOffset.UTC)); 636 assertEquals(trans.isValidOffset(OFFSET_ZERO), false); 637 assertEquals(trans.isValidOffset(OFFSET_PONE), true); 638 assertEquals(trans.isValidOffset(OFFSET_PTWO), true); 639 assertEquals(trans.isValidOffset(ZoneOffset.ofHours(3)), false); 640 assertEquals(trans.toString(), "Transition[Overlap at 2008-10-26T03:00+02:00 to +01:00]"); 641 642 assertFalse(trans.equals(null)); 643 assertFalse(trans.equals(OFFSET_PTWO)); 644 assertTrue(trans.equals(trans)); 645 646 final ZoneOffsetTransition otherTrans = test.getTransition(dateTime); 647 assertTrue(trans.equals(otherTrans)); 648 assertEquals(trans.hashCode(), otherTrans.hashCode()); 649 } 650 651 public void test_Paris_getStandardOffset() { 652 ZoneRules test = europeParis(); 653 ZonedDateTime zdt = createZDT(1840, 1, 1, ZoneOffset.UTC); 654 while (zdt.getYear() < 2010) { 655 Instant instant = zdt.toInstant(); 656 if (zdt.toLocalDate().isBefore(LocalDate.of(1911, 3, 11))) { 657 assertEquals(test.getStandardOffset(instant), ZoneOffset.ofHoursMinutesSeconds(0, 9, 21)); 658 } else if (zdt.toLocalDate().isBefore(LocalDate.of(1940, 6, 14))) { 659 assertEquals(test.getStandardOffset(instant), OFFSET_ZERO); 660 } else if (zdt.toLocalDate().isBefore(LocalDate.of(1944, 8, 25))) { 661 assertEquals(test.getStandardOffset(instant), OFFSET_PONE); 662 } else if (zdt.toLocalDate().isBefore(LocalDate.of(1945, 9, 16))) { 663 assertEquals(test.getStandardOffset(instant), OFFSET_ZERO); 664 } else { 665 assertEquals(test.getStandardOffset(instant), OFFSET_PONE); 666 } 667 zdt = zdt.plusMonths(6); 668 } 669 } 670 671 //----------------------------------------------------------------------- 672 // America/New_York 673 //----------------------------------------------------------------------- 674 private ZoneRules americaNewYork() { 675 return ZoneId.of("America/New_York").getRules(); 676 } 677 678 public void test_NewYork() { 679 ZoneRules test = americaNewYork(); 680 assertEquals(test.isFixedOffset(), false); 681 } 682 683 public void test_NewYork_preTimeZones() { 684 ZoneRules test = americaNewYork(); 685 ZonedDateTime old = createZDT(1800, 1, 1, ZoneOffset.UTC); 686 Instant instant = old.toInstant(); 687 ZoneOffset offset = ZoneOffset.of("-04:56:02"); 688 assertEquals(test.getOffset(instant), offset); 689 checkOffset(test, old.toLocalDateTime(), offset, 1); 690 assertEquals(test.getStandardOffset(instant), offset); 691 assertEquals(test.getDaylightSavings(instant), Duration.ZERO); 692 assertEquals(test.isDaylightSavings(instant), false); 693 } 694 695 public void test_NewYork_getOffset() { 696 ZoneRules test = americaNewYork(); 697 ZoneOffset offset = ZoneOffset.ofHours(-5); 698 assertEquals(test.getOffset(createInstant(2008, 1, 1, offset)), ZoneOffset.ofHours(-5)); 699 assertEquals(test.getOffset(createInstant(2008, 2, 1, offset)), ZoneOffset.ofHours(-5)); 700 assertEquals(test.getOffset(createInstant(2008, 3, 1, offset)), ZoneOffset.ofHours(-5)); 701 assertEquals(test.getOffset(createInstant(2008, 4, 1, offset)), ZoneOffset.ofHours(-4)); 702 assertEquals(test.getOffset(createInstant(2008, 5, 1, offset)), ZoneOffset.ofHours(-4)); 703 assertEquals(test.getOffset(createInstant(2008, 6, 1, offset)), ZoneOffset.ofHours(-4)); 704 assertEquals(test.getOffset(createInstant(2008, 7, 1, offset)), ZoneOffset.ofHours(-4)); 705 assertEquals(test.getOffset(createInstant(2008, 8, 1, offset)), ZoneOffset.ofHours(-4)); 706 assertEquals(test.getOffset(createInstant(2008, 9, 1, offset)), ZoneOffset.ofHours(-4)); 707 assertEquals(test.getOffset(createInstant(2008, 10, 1, offset)), ZoneOffset.ofHours(-4)); 708 assertEquals(test.getOffset(createInstant(2008, 11, 1, offset)), ZoneOffset.ofHours(-4)); 709 assertEquals(test.getOffset(createInstant(2008, 12, 1, offset)), ZoneOffset.ofHours(-5)); 710 assertEquals(test.getOffset(createInstant(2008, 1, 28, offset)), ZoneOffset.ofHours(-5)); 711 assertEquals(test.getOffset(createInstant(2008, 2, 28, offset)), ZoneOffset.ofHours(-5)); 712 assertEquals(test.getOffset(createInstant(2008, 3, 28, offset)), ZoneOffset.ofHours(-4)); 713 assertEquals(test.getOffset(createInstant(2008, 4, 28, offset)), ZoneOffset.ofHours(-4)); 714 assertEquals(test.getOffset(createInstant(2008, 5, 28, offset)), ZoneOffset.ofHours(-4)); 715 assertEquals(test.getOffset(createInstant(2008, 6, 28, offset)), ZoneOffset.ofHours(-4)); 716 assertEquals(test.getOffset(createInstant(2008, 7, 28, offset)), ZoneOffset.ofHours(-4)); 717 assertEquals(test.getOffset(createInstant(2008, 8, 28, offset)), ZoneOffset.ofHours(-4)); 718 assertEquals(test.getOffset(createInstant(2008, 9, 28, offset)), ZoneOffset.ofHours(-4)); 719 assertEquals(test.getOffset(createInstant(2008, 10, 28, offset)), ZoneOffset.ofHours(-4)); 720 assertEquals(test.getOffset(createInstant(2008, 11, 28, offset)), ZoneOffset.ofHours(-5)); 721 assertEquals(test.getOffset(createInstant(2008, 12, 28, offset)), ZoneOffset.ofHours(-5)); 722 } 723 724 public void test_NewYork_getOffset_toDST() { 725 ZoneRules test = americaNewYork(); 726 ZoneOffset offset = ZoneOffset.ofHours(-5); 727 assertEquals(test.getOffset(createInstant(2008, 3, 8, offset)), ZoneOffset.ofHours(-5)); 728 assertEquals(test.getOffset(createInstant(2008, 3, 9, offset)), ZoneOffset.ofHours(-5)); 729 assertEquals(test.getOffset(createInstant(2008, 3, 10, offset)), ZoneOffset.ofHours(-4)); 730 assertEquals(test.getOffset(createInstant(2008, 3, 11, offset)), ZoneOffset.ofHours(-4)); 731 assertEquals(test.getOffset(createInstant(2008, 3, 12, offset)), ZoneOffset.ofHours(-4)); 732 assertEquals(test.getOffset(createInstant(2008, 3, 13, offset)), ZoneOffset.ofHours(-4)); 733 assertEquals(test.getOffset(createInstant(2008, 3, 14, offset)), ZoneOffset.ofHours(-4)); 734 // cutover at 02:00 local 735 assertEquals(test.getOffset(createInstant(2008, 3, 9, 1, 59, 59, 999999999, offset)), ZoneOffset.ofHours(-5)); 736 assertEquals(test.getOffset(createInstant(2008, 3, 9, 2, 0, 0, 0, offset)), ZoneOffset.ofHours(-4)); 737 } 738 739 public void test_NewYork_getOffset_fromDST() { 740 ZoneRules test = americaNewYork(); 741 ZoneOffset offset = ZoneOffset.ofHours(-4); 742 assertEquals(test.getOffset(createInstant(2008, 11, 1, offset)), ZoneOffset.ofHours(-4)); 743 assertEquals(test.getOffset(createInstant(2008, 11, 2, offset)), ZoneOffset.ofHours(-4)); 744 assertEquals(test.getOffset(createInstant(2008, 11, 3, offset)), ZoneOffset.ofHours(-5)); 745 assertEquals(test.getOffset(createInstant(2008, 11, 4, offset)), ZoneOffset.ofHours(-5)); 746 assertEquals(test.getOffset(createInstant(2008, 11, 5, offset)), ZoneOffset.ofHours(-5)); 747 assertEquals(test.getOffset(createInstant(2008, 11, 6, offset)), ZoneOffset.ofHours(-5)); 748 assertEquals(test.getOffset(createInstant(2008, 11, 7, offset)), ZoneOffset.ofHours(-5)); 749 // cutover at 02:00 local 750 assertEquals(test.getOffset(createInstant(2008, 11, 2, 1, 59, 59, 999999999, offset)), ZoneOffset.ofHours(-4)); 751 assertEquals(test.getOffset(createInstant(2008, 11, 2, 2, 0, 0, 0, offset)), ZoneOffset.ofHours(-5)); 752 } 753 754 public void test_NewYork_getOffsetInfo() { 755 ZoneRules test = americaNewYork(); 756 checkOffset(test, createLDT(2008, 1, 1), ZoneOffset.ofHours(-5), 1); 757 checkOffset(test, createLDT(2008, 2, 1), ZoneOffset.ofHours(-5), 1); 758 checkOffset(test, createLDT(2008, 3, 1), ZoneOffset.ofHours(-5), 1); 759 checkOffset(test, createLDT(2008, 4, 1), ZoneOffset.ofHours(-4), 1); 760 checkOffset(test, createLDT(2008, 5, 1), ZoneOffset.ofHours(-4), 1); 761 checkOffset(test, createLDT(2008, 6, 1), ZoneOffset.ofHours(-4), 1); 762 checkOffset(test, createLDT(2008, 7, 1), ZoneOffset.ofHours(-4), 1); 763 checkOffset(test, createLDT(2008, 8, 1), ZoneOffset.ofHours(-4), 1); 764 checkOffset(test, createLDT(2008, 9, 1), ZoneOffset.ofHours(-4), 1); 765 checkOffset(test, createLDT(2008, 10, 1), ZoneOffset.ofHours(-4), 1); 766 checkOffset(test, createLDT(2008, 11, 1), ZoneOffset.ofHours(-4), 1); 767 checkOffset(test, createLDT(2008, 12, 1), ZoneOffset.ofHours(-5), 1); 768 checkOffset(test, createLDT(2008, 1, 28), ZoneOffset.ofHours(-5), 1); 769 checkOffset(test, createLDT(2008, 2, 28), ZoneOffset.ofHours(-5), 1); 770 checkOffset(test, createLDT(2008, 3, 28), ZoneOffset.ofHours(-4), 1); 771 checkOffset(test, createLDT(2008, 4, 28), ZoneOffset.ofHours(-4), 1); 772 checkOffset(test, createLDT(2008, 5, 28), ZoneOffset.ofHours(-4), 1); 773 checkOffset(test, createLDT(2008, 6, 28), ZoneOffset.ofHours(-4), 1); 774 checkOffset(test, createLDT(2008, 7, 28), ZoneOffset.ofHours(-4), 1); 775 checkOffset(test, createLDT(2008, 8, 28), ZoneOffset.ofHours(-4), 1); 776 checkOffset(test, createLDT(2008, 9, 28), ZoneOffset.ofHours(-4), 1); 777 checkOffset(test, createLDT(2008, 10, 28), ZoneOffset.ofHours(-4), 1); 778 checkOffset(test, createLDT(2008, 11, 28), ZoneOffset.ofHours(-5), 1); 779 checkOffset(test, createLDT(2008, 12, 28), ZoneOffset.ofHours(-5), 1); 780 } 781 782 public void test_NewYork_getOffsetInfo_toDST() { 783 ZoneRules test = americaNewYork(); 784 checkOffset(test, createLDT(2008, 3, 8), ZoneOffset.ofHours(-5), 1); 785 checkOffset(test, createLDT(2008, 3, 9), ZoneOffset.ofHours(-5), 1); 786 checkOffset(test, createLDT(2008, 3, 10), ZoneOffset.ofHours(-4), 1); 787 checkOffset(test, createLDT(2008, 3, 11), ZoneOffset.ofHours(-4), 1); 788 checkOffset(test, createLDT(2008, 3, 12), ZoneOffset.ofHours(-4), 1); 789 checkOffset(test, createLDT(2008, 3, 13), ZoneOffset.ofHours(-4), 1); 790 checkOffset(test, createLDT(2008, 3, 14), ZoneOffset.ofHours(-4), 1); 791 // cutover at 02:00 local 792 checkOffset(test, LocalDateTime.of(2008, 3, 9, 1, 59, 59, 999999999), ZoneOffset.ofHours(-5), 1); 793 checkOffset(test, LocalDateTime.of(2008, 3, 9, 3, 0, 0, 0), ZoneOffset.ofHours(-4), 1); 794 } 795 796 public void test_NewYork_getOffsetInfo_fromDST() { 797 ZoneRules test = americaNewYork(); 798 checkOffset(test, createLDT(2008, 11, 1), ZoneOffset.ofHours(-4), 1); 799 checkOffset(test, createLDT(2008, 11, 2), ZoneOffset.ofHours(-4), 1); 800 checkOffset(test, createLDT(2008, 11, 3), ZoneOffset.ofHours(-5), 1); 801 checkOffset(test, createLDT(2008, 11, 4), ZoneOffset.ofHours(-5), 1); 802 checkOffset(test, createLDT(2008, 11, 5), ZoneOffset.ofHours(-5), 1); 803 checkOffset(test, createLDT(2008, 11, 6), ZoneOffset.ofHours(-5), 1); 804 checkOffset(test, createLDT(2008, 11, 7), ZoneOffset.ofHours(-5), 1); 805 // cutover at 02:00 local 806 checkOffset(test, LocalDateTime.of(2008, 11, 2, 0, 59, 59, 999999999), ZoneOffset.ofHours(-4), 1); 807 checkOffset(test, LocalDateTime.of(2008, 11, 2, 2, 0, 0, 0), ZoneOffset.ofHours(-5), 1); 808 } 809 810 public void test_NewYork_getOffsetInfo_gap() { 811 ZoneRules test = americaNewYork(); 812 final LocalDateTime dateTime = LocalDateTime.of(2008, 3, 9, 2, 0, 0, 0); 813 ZoneOffsetTransition trans = checkOffset(test, dateTime, ZoneOffset.ofHours(-5), GAP); 814 assertEquals(trans.isGap(), true); 815 assertEquals(trans.isOverlap(), false); 816 assertEquals(trans.getOffsetBefore(), ZoneOffset.ofHours(-5)); 817 assertEquals(trans.getOffsetAfter(), ZoneOffset.ofHours(-4)); 818 assertEquals(trans.getInstant(), createInstant(2008, 3, 9, 2, 0, ZoneOffset.ofHours(-5))); 819 assertEquals(trans.isValidOffset(OFFSET_PTWO), false); 820 assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-5)), false); 821 assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-4)), false); 822 assertEquals(trans.toString(), "Transition[Gap at 2008-03-09T02:00-05:00 to -04:00]"); 823 824 assertFalse(trans.equals(null)); 825 assertFalse(trans.equals(ZoneOffset.ofHours(-5))); 826 assertTrue(trans.equals(trans)); 827 828 final ZoneOffsetTransition otherTrans = test.getTransition(dateTime); 829 assertTrue(trans.equals(otherTrans)); 830 assertEquals(trans.hashCode(), otherTrans.hashCode()); 831 } 832 833 public void test_NewYork_getOffsetInfo_overlap() { 834 ZoneRules test = americaNewYork(); 835 final LocalDateTime dateTime = LocalDateTime.of(2008, 11, 2, 1, 0, 0, 0); 836 ZoneOffsetTransition trans = checkOffset(test, dateTime, ZoneOffset.ofHours(-4), OVERLAP); 837 assertEquals(trans.isGap(), false); 838 assertEquals(trans.isOverlap(), true); 839 assertEquals(trans.getOffsetBefore(), ZoneOffset.ofHours(-4)); 840 assertEquals(trans.getOffsetAfter(), ZoneOffset.ofHours(-5)); 841 assertEquals(trans.getInstant(), createInstant(2008, 11, 2, 2, 0, ZoneOffset.ofHours(-4))); 842 assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-1)), false); 843 assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-5)), true); 844 assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-4)), true); 845 assertEquals(trans.isValidOffset(OFFSET_PTWO), false); 846 assertEquals(trans.toString(), "Transition[Overlap at 2008-11-02T02:00-04:00 to -05:00]"); 847 848 assertFalse(trans.equals(null)); 849 assertFalse(trans.equals(ZoneOffset.ofHours(-4))); 850 assertTrue(trans.equals(trans)); 851 852 final ZoneOffsetTransition otherTrans = test.getTransition(dateTime); 853 assertTrue(trans.equals(otherTrans)); 854 assertEquals(trans.hashCode(), otherTrans.hashCode()); 855 } 856 857 public void test_NewYork_getStandardOffset() { 858 ZoneRules test = americaNewYork(); 859 ZonedDateTime dateTime = createZDT(1860, 1, 1, ZoneOffset.UTC); 860 while (dateTime.getYear() < 2010) { 861 Instant instant = dateTime.toInstant(); 862 if (dateTime.toLocalDate().isBefore(LocalDate.of(1883, 11, 18))) { 863 assertEquals(test.getStandardOffset(instant), ZoneOffset.of("-04:56:02")); 864 } else { 865 assertEquals(test.getStandardOffset(instant), ZoneOffset.ofHours(-5)); 866 } 867 dateTime = dateTime.plusMonths(6); 868 } 869 } 870 871 //----------------------------------------------------------------------- 872 // Kathmandu 873 //----------------------------------------------------------------------- 874 private ZoneRules asiaKathmandu() { 875 return ZoneId.of("Asia/Kathmandu").getRules(); 876 } 877 878 public void test_Kathmandu_nextTransition_historic() { 879 ZoneRules test = asiaKathmandu(); 880 List<ZoneOffsetTransition> trans = test.getTransitions(); 881 882 ZoneOffsetTransition first = trans.get(0); 883 assertEquals(test.nextTransition(first.getInstant().minusNanos(1)), first); 884 885 for (int i = 0; i < trans.size() - 1; i++) { 886 ZoneOffsetTransition cur = trans.get(i); 887 ZoneOffsetTransition next = trans.get(i + 1); 888 889 assertEquals(test.nextTransition(cur.getInstant()), next); 890 assertEquals(test.nextTransition(next.getInstant().minusNanos(1)), next); 891 } 892 } 893 894 public void test_Kathmandu_nextTransition_noRules() { 895 ZoneRules test = asiaKathmandu(); 896 List<ZoneOffsetTransition> trans = test.getTransitions(); 897 898 ZoneOffsetTransition last = trans.get(trans.size() - 1); 899 assertEquals(test.nextTransition(last.getInstant()), null); 900 } 901 902 //----------------------------------------------------------------------- 903 // Apia 904 //----------------------------------------------------------------------- 905 private ZoneRules pacificApia() { 906 return ZoneId.of("Pacific/Apia").getRules(); 907 } 908 909 public void test_Apia_nextTransition_historic() { 910 ZoneRules test = pacificApia(); 911 List<ZoneOffsetTransition> trans = test.getTransitions(); 912 913 ZoneOffsetTransition first = trans.get(0); 914 assertEquals(test.nextTransition(first.getInstant().minusNanos(1)), first); 915 916 for (int i = 0; i < trans.size() - 1; i++) { 917 ZoneOffsetTransition cur = trans.get(i); 918 ZoneOffsetTransition next = trans.get(i + 1); 919 920 assertEquals(test.nextTransition(cur.getInstant()), next); 921 assertEquals(test.nextTransition(next.getInstant().minusNanos(1)), next); 922 } 923 } 924 925 public void test_Apia_jumpOverInternationalDateLine_M10_to_P14() { 926 // transition occurred at 2011-12-30T00:00-10:00 927 ZoneRules test = pacificApia(); 928 Instant instantBefore = LocalDate.of(2011, 12, 27).atStartOfDay(ZoneOffset.UTC).toInstant(); 929 ZoneOffsetTransition trans = test.nextTransition(instantBefore); 930 assertEquals(trans.getDateTimeBefore(), LocalDateTime.of(2011, 12, 30, 0, 0)); 931 assertEquals(trans.getDateTimeAfter(), LocalDateTime.of(2011, 12, 31, 0, 0)); 932 assertEquals(trans.isGap(), true); 933 assertEquals(trans.isOverlap(), false); 934 assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-10)), false); 935 assertEquals(trans.isValidOffset(ZoneOffset.ofHours(+14)), false); 936 assertEquals(trans.getDuration(), Duration.ofHours(24)); 937 assertEquals(trans.getInstant(), LocalDateTime.of(2011, 12, 31, 0, 0).toInstant(ZoneOffset.ofHours(+14))); 938 939 ZonedDateTime zdt = ZonedDateTime.of(2011, 12, 29, 23, 0, 0, 0, ZoneId.of("Pacific/Apia")); 940 assertEquals(zdt.plusHours(2).toLocalDateTime(), LocalDateTime.of(2011, 12, 31, 1, 0)); 941 } 942 943 public void test_Apia_jumpForwardOverInternationalDateLine_P12_to_M12() { 944 // transition occurred at 1879-07-04T00:00+12:33:04 945 ZoneRules test = pacificApia(); 946 Instant instantBefore = LocalDate.of(1879, 7, 2).atStartOfDay(ZoneOffset.UTC).toInstant(); 947 ZoneOffsetTransition trans = test.nextTransition(instantBefore); 948 assertEquals(trans.getDateTimeBefore(), LocalDateTime.of(1879, 7, 5, 0, 0)); 949 assertEquals(trans.getDateTimeAfter(), LocalDateTime.of(1879, 7, 4, 0, 0)); 950 assertEquals(trans.isGap(), false); 951 assertEquals(trans.isOverlap(), true); 952 assertEquals(trans.isValidOffset(ZoneOffset.ofHoursMinutesSeconds(+12, 33, 4)), true); 953 assertEquals(trans.isValidOffset(ZoneOffset.ofHoursMinutesSeconds(-11, -26, -56)), true); 954 assertEquals(trans.getDuration(), Duration.ofHours(-24)); 955 assertEquals(trans.getInstant(), LocalDateTime.of(1879, 7, 4, 0, 0).toInstant(ZoneOffset.ofHoursMinutesSeconds(-11, -26, -56))); 956 957 ZonedDateTime zdt = ZonedDateTime.of(1879, 7, 4, 23, 0, 0, 0, ZoneId.of("Pacific/Apia")); 958 assertEquals(zdt.plusHours(2).toLocalDateTime(), LocalDateTime.of(1879, 7, 4, 1, 0, 0)); 959 } 960 961 //------------------------------------------------------------------------- 962 @Test(expectedExceptions=UnsupportedOperationException.class) 963 public void test_getTransitions_immutable() { 964 ZoneRules test = europeParis(); 965 test.getTransitions().clear(); 966 } 967 968 @Test(expectedExceptions=UnsupportedOperationException.class) 969 public void test_getTransitionRules_immutable() { 970 ZoneRules test = europeParis(); 971 test.getTransitionRules().clear(); 972 } 973 974 //----------------------------------------------------------------------- 975 // of() 976 //----------------------------------------------------------------------- 977 public void test_of(){ 978 //used for standard offset 979 ZoneOffset stdOffset1 = ZoneOffset.UTC; 980 ZoneOffset stdOffset2 = ZoneOffset.ofHours(1); 981 LocalDateTime time_of_stdOffsetTransition1 = LocalDateTime.of(2013, 1, 5, 1, 0); 982 ZoneOffsetTransition stdOffsetTransition1 = ZoneOffsetTransition.of(time_of_stdOffsetTransition1, stdOffset1, stdOffset2); 983 List<ZoneOffsetTransition> stdOffsetTransition_list = new ArrayList<ZoneOffsetTransition>(); 984 stdOffsetTransition_list.add(stdOffsetTransition1); 985 986 //used for wall offset 987 ZoneOffset wallOffset1 = ZoneOffset.ofHours(2); 988 ZoneOffset wallOffset2 = ZoneOffset.ofHours(4); 989 ZoneOffset wallOffset3 = ZoneOffset.ofHours(7); 990 991 LocalDateTime time_of_wallOffsetTransition1 = LocalDateTime.of(2013, 2, 5, 1, 0); 992 LocalDateTime time_of_wallOffsetTransition2 = LocalDateTime.of(2013, 3, 5, 1, 0); 993 LocalDateTime time_of_wallOffsetTransition3 = LocalDateTime.of(2013, 10, 5, 1, 0); 994 995 ZoneOffsetTransition wallOffsetTransition1 = ZoneOffsetTransition.of(time_of_wallOffsetTransition1, wallOffset1, wallOffset2); 996 ZoneOffsetTransition wallOffsetTransition2 = ZoneOffsetTransition.of(time_of_wallOffsetTransition2, wallOffset2, wallOffset3); 997 ZoneOffsetTransition wallOffsetTransition3 = ZoneOffsetTransition.of(time_of_wallOffsetTransition3, wallOffset3, wallOffset1); 998 999 List<ZoneOffsetTransition> wallOffsetTransition_list = new ArrayList<ZoneOffsetTransition>(); 1000 wallOffsetTransition_list.add(wallOffsetTransition1); 1001 wallOffsetTransition_list.add(wallOffsetTransition2); 1002 wallOffsetTransition_list.add(wallOffsetTransition3); 1003 1004 //used for ZoneOffsetTransitionRule 1005 ZoneOffset ruleOffset = ZoneOffset.ofHours(3); 1006 ZoneOffsetTransitionRule.TimeDefinition timeDefinition = ZoneOffsetTransitionRule.TimeDefinition.valueOf("WALL"); 1007 ZoneOffsetTransitionRule rule1 = ZoneOffsetTransitionRule.of(Month.FEBRUARY, 1008 2, 1009 DayOfWeek.MONDAY, 1010 LocalTime.of(1, 0), 1011 false, 1012 timeDefinition, 1013 ZoneOffset.UTC, 1014 ZoneOffset.UTC, 1015 ruleOffset 1016 ); 1017 List<ZoneOffsetTransitionRule> rule_list = new ArrayList<ZoneOffsetTransitionRule>(); 1018 rule_list.add(rule1); 1019 1020 //Begin verification 1021 ZoneRules zoneRule = ZoneRules.of(stdOffset1, 1022 wallOffset1, 1023 stdOffsetTransition_list, 1024 wallOffsetTransition_list, 1025 rule_list 1026 ); 1027 1028 OffsetDateTime before_time_of_stdOffsetTransition1 = OffsetDateTime.of(time_of_stdOffsetTransition1, stdOffset1).minusSeconds(1); 1029 OffsetDateTime after_time_of_stdOffsetTransition1 = OffsetDateTime.of(time_of_stdOffsetTransition1, stdOffset1).plusSeconds(1);; 1030 assertEquals(zoneRule.getStandardOffset(before_time_of_stdOffsetTransition1.toInstant()), stdOffset1); 1031 assertEquals(zoneRule.getStandardOffset(after_time_of_stdOffsetTransition1.toInstant()), stdOffset2); 1032 1033 OffsetDateTime before_time_of_wallOffsetTransition1 = OffsetDateTime.of(time_of_wallOffsetTransition1, wallOffset1).minusSeconds(1); 1034 OffsetDateTime after_time_of_wallOffsetTransition1 = OffsetDateTime.of(time_of_wallOffsetTransition1, wallOffset1).plusSeconds(1); 1035 assertEquals(zoneRule.nextTransition(before_time_of_wallOffsetTransition1.toInstant()), wallOffsetTransition1); 1036 assertEquals(zoneRule.nextTransition(after_time_of_wallOffsetTransition1.toInstant()), wallOffsetTransition2); 1037 1038 OffsetDateTime before_time_of_wallOffsetTransition2 = OffsetDateTime.of(time_of_wallOffsetTransition2, wallOffset2).minusSeconds(1); 1039 OffsetDateTime after_time_of_wallOffsetTransition2 = OffsetDateTime.of(time_of_wallOffsetTransition2, wallOffset2).plusSeconds(1); 1040 assertEquals(zoneRule.nextTransition(before_time_of_wallOffsetTransition2.toInstant()), wallOffsetTransition2); 1041 assertEquals(zoneRule.nextTransition(after_time_of_wallOffsetTransition2.toInstant()), wallOffsetTransition3); 1042 1043 OffsetDateTime before_time_of_wallOffsetTransition3 = OffsetDateTime.of(time_of_wallOffsetTransition3, wallOffset3).minusSeconds(1); 1044 OffsetDateTime after_time_of_wallOffsetTransition3 = OffsetDateTime.of(time_of_wallOffsetTransition3, wallOffset3).plusSeconds(1); 1045 assertEquals(zoneRule.nextTransition(before_time_of_wallOffsetTransition3.toInstant()), wallOffsetTransition3); 1046 assertEquals(zoneRule.nextTransition(after_time_of_wallOffsetTransition3.toInstant()), rule1.createTransition(2014)); 1047 } 1048 1049 //----------------------------------------------------------------------- 1050 // equals() / hashCode() 1051 //----------------------------------------------------------------------- 1052 public void test_equals() { 1053 ZoneRules test1 = europeLondon(); 1054 ZoneRules test2 = europeParis(); 1055 ZoneRules test2b = europeParis(); 1056 assertEquals(test1.equals(test2), false); 1057 assertEquals(test2.equals(test1), false); 1058 1059 assertEquals(test1.equals(test1), true); 1060 assertEquals(test2.equals(test2), true); 1061 assertEquals(test2.equals(test2b), true); 1062 1063 assertEquals(test1.hashCode() == test1.hashCode(), true); 1064 assertEquals(test2.hashCode() == test2.hashCode(), true); 1065 assertEquals(test2.hashCode() == test2b.hashCode(), true); 1066 } 1067 1068 public void test_equals_null() { 1069 assertEquals(europeLondon().equals(null), false); 1070 } 1071 1072 public void test_equals_notZoneRules() { 1073 assertEquals(europeLondon().equals("Europe/London"), false); 1074 } 1075 1076 public void test_toString() { 1077 assertEquals(europeLondon().toString().contains("ZoneRules"), true); 1078 } 1079 1080 //----------------------------------------------------------------------- 1081 //----------------------------------------------------------------------- 1082 //----------------------------------------------------------------------- 1083 private Instant createInstant(int year, int month, int day, ZoneOffset offset) { 1084 return LocalDateTime.of(year, month, day, 0, 0).toInstant(offset); 1085 } 1086 1087 private Instant createInstant(int year, int month, int day, int hour, int min, ZoneOffset offset) { 1088 return LocalDateTime.of(year, month, day, hour, min).toInstant(offset); 1089 } 1090 1091 private Instant createInstant(int year, int month, int day, int hour, int min, int sec, int nano, ZoneOffset offset) { 1092 return LocalDateTime.of(year, month, day, hour, min, sec, nano).toInstant(offset); 1093 } 1094 1095 private ZonedDateTime createZDT(int year, int month, int day, ZoneId zone) { 1096 return LocalDateTime.of(year, month, day, 0, 0).atZone(zone); 1097 } 1098 1099 private LocalDateTime createLDT(int year, int month, int day) { 1100 return LocalDateTime.of(year, month, day, 0, 0); 1101 } 1102 1103 private ZoneOffsetTransition checkOffset(ZoneRules rules, LocalDateTime dateTime, ZoneOffset offset, int type) { 1104 List<ZoneOffset> validOffsets = rules.getValidOffsets(dateTime); 1105 assertEquals(validOffsets.size(), type); 1106 assertEquals(rules.getOffset(dateTime), offset); 1107 if (type == 1) { 1108 assertEquals(validOffsets.get(0), offset); 1109 return null; 1110 } else { 1111 ZoneOffsetTransition zot = rules.getTransition(dateTime); 1112 assertNotNull(zot); 1113 assertEquals(zot.isOverlap(), type == 2); 1114 assertEquals(zot.isGap(), type == 0); 1115 assertEquals(zot.isValidOffset(offset), type == 2); 1116 return zot; 1117 } 1118 } 1119 1120} 1121