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 // Android-changed: check for -1, which matches the data, we don't do the "optimization" 376 assertEquals(in.getDayOfMonthIndicator(), -1); // optimized from -1 377 assertEquals(in.getDayOfWeek(), DayOfWeek.SUNDAY); 378 assertEquals(in.getLocalTime(), LocalTime.of(1, 0)); 379 assertEquals(in.getTimeDefinition(), TimeDefinition.UTC); 380 assertEquals(in.getStandardOffset(), OFFSET_ZERO); 381 assertEquals(in.getOffsetBefore(), OFFSET_ZERO); 382 assertEquals(in.getOffsetAfter(), OFFSET_PONE); 383 384 ZoneOffsetTransitionRule out = rules.get(1); 385 assertEquals(out.getMonth(), Month.OCTOBER); 386 // Android-changed: check for -1, which matches the data, we don't do the "optimization" 387 assertEquals(out.getDayOfMonthIndicator(), -1); // optimized from -1 388 assertEquals(out.getDayOfWeek(), DayOfWeek.SUNDAY); 389 assertEquals(out.getLocalTime(), LocalTime.of(1, 0)); 390 assertEquals(out.getTimeDefinition(), TimeDefinition.UTC); 391 assertEquals(out.getStandardOffset(), OFFSET_ZERO); 392 assertEquals(out.getOffsetBefore(), OFFSET_PONE); 393 assertEquals(out.getOffsetAfter(), OFFSET_ZERO); 394 } 395 396 //----------------------------------------------------------------------- 397 public void test_London_nextTransition_historic() { 398 ZoneRules test = europeLondon(); 399 List<ZoneOffsetTransition> trans = test.getTransitions(); 400 401 ZoneOffsetTransition first = trans.get(0); 402 assertEquals(test.nextTransition(first.getInstant().minusNanos(1)), first); 403 404 for (int i = 0; i < trans.size() - 1; i++) { 405 ZoneOffsetTransition cur = trans.get(i); 406 ZoneOffsetTransition next = trans.get(i + 1); 407 408 assertEquals(test.nextTransition(cur.getInstant()), next); 409 assertEquals(test.nextTransition(next.getInstant().minusNanos(1)), next); 410 } 411 } 412 413 public void test_London_nextTransition_rulesBased() { 414 ZoneRules test = europeLondon(); 415 List<ZoneOffsetTransitionRule> rules = test.getTransitionRules(); 416 List<ZoneOffsetTransition> trans = test.getTransitions(); 417 418 ZoneOffsetTransition last = trans.get(trans.size() - 1); 419 assertEquals(test.nextTransition(last.getInstant()), rules.get(0).createTransition(1998)); 420 421 for (int year = 1998; year < 2010; year++) { 422 ZoneOffsetTransition a = rules.get(0).createTransition(year); 423 ZoneOffsetTransition b = rules.get(1).createTransition(year); 424 ZoneOffsetTransition c = rules.get(0).createTransition(year + 1); 425 426 assertEquals(test.nextTransition(a.getInstant()), b); 427 assertEquals(test.nextTransition(b.getInstant().minusNanos(1)), b); 428 429 assertEquals(test.nextTransition(b.getInstant()), c); 430 assertEquals(test.nextTransition(c.getInstant().minusNanos(1)), c); 431 } 432 } 433 434 public void test_London_nextTransition_lastYear() { 435 ZoneRules test = europeLondon(); 436 List<ZoneOffsetTransitionRule> rules = test.getTransitionRules(); 437 ZoneOffsetTransition zot = rules.get(1).createTransition(Year.MAX_VALUE); 438 assertEquals(test.nextTransition(zot.getInstant()), null); 439 } 440 441 //----------------------------------------------------------------------- 442 public void test_London_previousTransition_historic() { 443 ZoneRules test = europeLondon(); 444 List<ZoneOffsetTransition> trans = test.getTransitions(); 445 446 ZoneOffsetTransition first = trans.get(0); 447 assertEquals(test.previousTransition(first.getInstant()), null); 448 assertEquals(test.previousTransition(first.getInstant().minusNanos(1)), null); 449 450 for (int i = 0; i < trans.size() - 1; i++) { 451 ZoneOffsetTransition prev = trans.get(i); 452 ZoneOffsetTransition cur = trans.get(i + 1); 453 454 assertEquals(test.previousTransition(cur.getInstant()), prev); 455 assertEquals(test.previousTransition(prev.getInstant().plusSeconds(1)), prev); 456 assertEquals(test.previousTransition(prev.getInstant().plusNanos(1)), prev); 457 } 458 } 459 460 public void test_London_previousTransition_rulesBased() { 461 ZoneRules test = europeLondon(); 462 List<ZoneOffsetTransitionRule> rules = test.getTransitionRules(); 463 List<ZoneOffsetTransition> trans = test.getTransitions(); 464 465 ZoneOffsetTransition last = trans.get(trans.size() - 1); 466 assertEquals(test.previousTransition(last.getInstant().plusSeconds(1)), last); 467 assertEquals(test.previousTransition(last.getInstant().plusNanos(1)), last); 468 469 // Jan 1st of year between transitions and rules 470 ZonedDateTime odt = ZonedDateTime.ofInstant(last.getInstant(), last.getOffsetAfter()); 471 odt = odt.withDayOfYear(1).plusYears(1).with(LocalTime.MIDNIGHT); 472 assertEquals(test.previousTransition(odt.toInstant()), last); 473 474 // later years 475 for (int year = 1998; year < 2010; year++) { 476 ZoneOffsetTransition a = rules.get(0).createTransition(year); 477 ZoneOffsetTransition b = rules.get(1).createTransition(year); 478 ZoneOffsetTransition c = rules.get(0).createTransition(year + 1); 479 480 assertEquals(test.previousTransition(c.getInstant()), b); 481 assertEquals(test.previousTransition(b.getInstant().plusSeconds(1)), b); 482 assertEquals(test.previousTransition(b.getInstant().plusNanos(1)), b); 483 484 assertEquals(test.previousTransition(b.getInstant()), a); 485 assertEquals(test.previousTransition(a.getInstant().plusSeconds(1)), a); 486 assertEquals(test.previousTransition(a.getInstant().plusNanos(1)), a); 487 } 488 } 489 490 //----------------------------------------------------------------------- 491 // Europe/Paris 492 //----------------------------------------------------------------------- 493 private ZoneRules europeParis() { 494 return ZoneId.of("Europe/Paris").getRules(); 495 } 496 497 public void test_Paris() { 498 ZoneRules test = europeParis(); 499 assertEquals(test.isFixedOffset(), false); 500 } 501 502 public void test_Paris_preTimeZones() { 503 ZoneRules test = europeParis(); 504 ZonedDateTime old = createZDT(1800, 1, 1, ZoneOffset.UTC); 505 Instant instant = old.toInstant(); 506 ZoneOffset offset = ZoneOffset.ofHoursMinutesSeconds(0, 9, 21); 507 assertEquals(test.getOffset(instant), offset); 508 checkOffset(test, old.toLocalDateTime(), offset, 1); 509 assertEquals(test.getStandardOffset(instant), offset); 510 assertEquals(test.getDaylightSavings(instant), Duration.ZERO); 511 assertEquals(test.isDaylightSavings(instant), false); 512 } 513 514 public void test_Paris_getOffset() { 515 ZoneRules test = europeParis(); 516 assertEquals(test.getOffset(createInstant(2008, 1, 1, ZoneOffset.UTC)), OFFSET_PONE); 517 assertEquals(test.getOffset(createInstant(2008, 2, 1, ZoneOffset.UTC)), OFFSET_PONE); 518 assertEquals(test.getOffset(createInstant(2008, 3, 1, ZoneOffset.UTC)), OFFSET_PONE); 519 assertEquals(test.getOffset(createInstant(2008, 4, 1, ZoneOffset.UTC)), OFFSET_PTWO); 520 assertEquals(test.getOffset(createInstant(2008, 5, 1, ZoneOffset.UTC)), OFFSET_PTWO); 521 assertEquals(test.getOffset(createInstant(2008, 6, 1, ZoneOffset.UTC)), OFFSET_PTWO); 522 assertEquals(test.getOffset(createInstant(2008, 7, 1, ZoneOffset.UTC)), OFFSET_PTWO); 523 assertEquals(test.getOffset(createInstant(2008, 8, 1, ZoneOffset.UTC)), OFFSET_PTWO); 524 assertEquals(test.getOffset(createInstant(2008, 9, 1, ZoneOffset.UTC)), OFFSET_PTWO); 525 assertEquals(test.getOffset(createInstant(2008, 10, 1, ZoneOffset.UTC)), OFFSET_PTWO); 526 assertEquals(test.getOffset(createInstant(2008, 11, 1, ZoneOffset.UTC)), OFFSET_PONE); 527 assertEquals(test.getOffset(createInstant(2008, 12, 1, ZoneOffset.UTC)), OFFSET_PONE); 528 } 529 530 public void test_Paris_getOffset_toDST() { 531 ZoneRules test = europeParis(); 532 assertEquals(test.getOffset(createInstant(2008, 3, 24, ZoneOffset.UTC)), OFFSET_PONE); 533 assertEquals(test.getOffset(createInstant(2008, 3, 25, ZoneOffset.UTC)), OFFSET_PONE); 534 assertEquals(test.getOffset(createInstant(2008, 3, 26, ZoneOffset.UTC)), OFFSET_PONE); 535 assertEquals(test.getOffset(createInstant(2008, 3, 27, ZoneOffset.UTC)), OFFSET_PONE); 536 assertEquals(test.getOffset(createInstant(2008, 3, 28, ZoneOffset.UTC)), OFFSET_PONE); 537 assertEquals(test.getOffset(createInstant(2008, 3, 29, ZoneOffset.UTC)), OFFSET_PONE); 538 assertEquals(test.getOffset(createInstant(2008, 3, 30, ZoneOffset.UTC)), OFFSET_PONE); 539 assertEquals(test.getOffset(createInstant(2008, 3, 31, ZoneOffset.UTC)), OFFSET_PTWO); 540 // cutover at 01:00Z 541 assertEquals(test.getOffset(createInstant(2008, 3, 30, 0, 59, 59, 999999999, ZoneOffset.UTC)), OFFSET_PONE); 542 assertEquals(test.getOffset(createInstant(2008, 3, 30, 1, 0, 0, 0, ZoneOffset.UTC)), OFFSET_PTWO); 543 } 544 545 public void test_Paris_getOffset_fromDST() { 546 ZoneRules test = europeParis(); 547 assertEquals(test.getOffset(createInstant(2008, 10, 24, ZoneOffset.UTC)), OFFSET_PTWO); 548 assertEquals(test.getOffset(createInstant(2008, 10, 25, ZoneOffset.UTC)), OFFSET_PTWO); 549 assertEquals(test.getOffset(createInstant(2008, 10, 26, ZoneOffset.UTC)), OFFSET_PTWO); 550 assertEquals(test.getOffset(createInstant(2008, 10, 27, ZoneOffset.UTC)), OFFSET_PONE); 551 assertEquals(test.getOffset(createInstant(2008, 10, 28, ZoneOffset.UTC)), OFFSET_PONE); 552 assertEquals(test.getOffset(createInstant(2008, 10, 29, ZoneOffset.UTC)), OFFSET_PONE); 553 assertEquals(test.getOffset(createInstant(2008, 10, 30, ZoneOffset.UTC)), OFFSET_PONE); 554 assertEquals(test.getOffset(createInstant(2008, 10, 31, ZoneOffset.UTC)), OFFSET_PONE); 555 // cutover at 01:00Z 556 assertEquals(test.getOffset(createInstant(2008, 10, 26, 0, 59, 59, 999999999, ZoneOffset.UTC)), OFFSET_PTWO); 557 assertEquals(test.getOffset(createInstant(2008, 10, 26, 1, 0, 0, 0, ZoneOffset.UTC)), OFFSET_PONE); 558 } 559 560 public void test_Paris_getOffsetInfo() { 561 ZoneRules test = europeParis(); 562 checkOffset(test, createLDT(2008, 1, 1), OFFSET_PONE, 1); 563 checkOffset(test, createLDT(2008, 2, 1), OFFSET_PONE, 1); 564 checkOffset(test, createLDT(2008, 3, 1), OFFSET_PONE, 1); 565 checkOffset(test, createLDT(2008, 4, 1), OFFSET_PTWO, 1); 566 checkOffset(test, createLDT(2008, 5, 1), OFFSET_PTWO, 1); 567 checkOffset(test, createLDT(2008, 6, 1), OFFSET_PTWO, 1); 568 checkOffset(test, createLDT(2008, 7, 1), OFFSET_PTWO, 1); 569 checkOffset(test, createLDT(2008, 8, 1), OFFSET_PTWO, 1); 570 checkOffset(test, createLDT(2008, 9, 1), OFFSET_PTWO, 1); 571 checkOffset(test, createLDT(2008, 10, 1), OFFSET_PTWO, 1); 572 checkOffset(test, createLDT(2008, 11, 1), OFFSET_PONE, 1); 573 checkOffset(test, createLDT(2008, 12, 1), OFFSET_PONE, 1); 574 } 575 576 public void test_Paris_getOffsetInfo_toDST() { 577 ZoneRules test = europeParis(); 578 checkOffset(test, createLDT(2008, 3, 24), OFFSET_PONE, 1); 579 checkOffset(test, createLDT(2008, 3, 25), OFFSET_PONE, 1); 580 checkOffset(test, createLDT(2008, 3, 26), OFFSET_PONE, 1); 581 checkOffset(test, createLDT(2008, 3, 27), OFFSET_PONE, 1); 582 checkOffset(test, createLDT(2008, 3, 28), OFFSET_PONE, 1); 583 checkOffset(test, createLDT(2008, 3, 29), OFFSET_PONE, 1); 584 checkOffset(test, createLDT(2008, 3, 30), OFFSET_PONE, 1); 585 checkOffset(test, createLDT(2008, 3, 31), OFFSET_PTWO, 1); 586 // cutover at 01:00Z which is 02:00+01:00(local Paris time) 587 checkOffset(test, LocalDateTime.of(2008, 3, 30, 1, 59, 59, 999999999), OFFSET_PONE, 1); 588 checkOffset(test, LocalDateTime.of(2008, 3, 30, 3, 0, 0, 0), OFFSET_PTWO, 1); 589 } 590 591 public void test_Paris_getOffsetInfo_fromDST() { 592 ZoneRules test = europeParis(); 593 checkOffset(test, createLDT(2008, 10, 24), OFFSET_PTWO, 1); 594 checkOffset(test, createLDT(2008, 10, 25), OFFSET_PTWO, 1); 595 checkOffset(test, createLDT(2008, 10, 26), OFFSET_PTWO, 1); 596 checkOffset(test, createLDT(2008, 10, 27), OFFSET_PONE, 1); 597 checkOffset(test, createLDT(2008, 10, 28), OFFSET_PONE, 1); 598 checkOffset(test, createLDT(2008, 10, 29), OFFSET_PONE, 1); 599 checkOffset(test, createLDT(2008, 10, 30), OFFSET_PONE, 1); 600 checkOffset(test, createLDT(2008, 10, 31), OFFSET_PONE, 1); 601 // cutover at 01:00Z which is 02:00+01:00(local Paris time) 602 checkOffset(test, LocalDateTime.of(2008, 10, 26, 1, 59, 59, 999999999), OFFSET_PTWO, 1); 603 checkOffset(test, LocalDateTime.of(2008, 10, 26, 3, 0, 0, 0), OFFSET_PONE, 1); 604 } 605 606 public void test_Paris_getOffsetInfo_gap() { 607 ZoneRules test = europeParis(); 608 final LocalDateTime dateTime = LocalDateTime.of(2008, 3, 30, 2, 0, 0, 0); 609 ZoneOffsetTransition trans = checkOffset(test, dateTime, OFFSET_PONE, GAP); 610 assertEquals(trans.isGap(), true); 611 assertEquals(trans.isOverlap(), false); 612 assertEquals(trans.getOffsetBefore(), OFFSET_PONE); 613 assertEquals(trans.getOffsetAfter(), OFFSET_PTWO); 614 assertEquals(trans.getInstant(), createInstant(2008, 3, 30, 1, 0, ZoneOffset.UTC)); 615 assertEquals(trans.isValidOffset(OFFSET_ZERO), false); 616 assertEquals(trans.isValidOffset(OFFSET_PONE), false); 617 assertEquals(trans.isValidOffset(OFFSET_PTWO), false); 618 assertEquals(trans.toString(), "Transition[Gap at 2008-03-30T02:00+01:00 to +02:00]"); 619 620 assertFalse(trans.equals(null)); 621 assertFalse(trans.equals(OFFSET_PONE)); 622 assertTrue(trans.equals(trans)); 623 624 final ZoneOffsetTransition otherTrans = test.getTransition(dateTime); 625 assertTrue(trans.equals(otherTrans)); 626 assertEquals(trans.hashCode(), otherTrans.hashCode()); 627 } 628 629 public void test_Paris_getOffsetInfo_overlap() { 630 ZoneRules test = europeParis(); 631 final LocalDateTime dateTime = LocalDateTime.of(2008, 10, 26, 2, 0, 0, 0); 632 ZoneOffsetTransition trans = checkOffset(test, dateTime, OFFSET_PTWO, OVERLAP); 633 assertEquals(trans.isGap(), false); 634 assertEquals(trans.isOverlap(), true); 635 assertEquals(trans.getOffsetBefore(), OFFSET_PTWO); 636 assertEquals(trans.getOffsetAfter(), OFFSET_PONE); 637 assertEquals(trans.getInstant(), createInstant(2008, 10, 26, 1, 0, ZoneOffset.UTC)); 638 assertEquals(trans.isValidOffset(OFFSET_ZERO), false); 639 assertEquals(trans.isValidOffset(OFFSET_PONE), true); 640 assertEquals(trans.isValidOffset(OFFSET_PTWO), true); 641 assertEquals(trans.isValidOffset(ZoneOffset.ofHours(3)), false); 642 assertEquals(trans.toString(), "Transition[Overlap at 2008-10-26T03:00+02:00 to +01:00]"); 643 644 assertFalse(trans.equals(null)); 645 assertFalse(trans.equals(OFFSET_PTWO)); 646 assertTrue(trans.equals(trans)); 647 648 final ZoneOffsetTransition otherTrans = test.getTransition(dateTime); 649 assertTrue(trans.equals(otherTrans)); 650 assertEquals(trans.hashCode(), otherTrans.hashCode()); 651 } 652 653 public void test_Paris_getStandardOffset() { 654 ZoneRules test = europeParis(); 655 ZonedDateTime zdt = createZDT(1840, 1, 1, ZoneOffset.UTC); 656 while (zdt.getYear() < 2010) { 657 Instant instant = zdt.toInstant(); 658 if (zdt.toLocalDate().isBefore(LocalDate.of(1911, 3, 11))) { 659 assertEquals(test.getStandardOffset(instant), ZoneOffset.ofHoursMinutesSeconds(0, 9, 21)); 660 } else if (zdt.toLocalDate().isBefore(LocalDate.of(1940, 6, 14))) { 661 assertEquals(test.getStandardOffset(instant), OFFSET_ZERO); 662 } else if (zdt.toLocalDate().isBefore(LocalDate.of(1944, 8, 25))) { 663 assertEquals(test.getStandardOffset(instant), OFFSET_PONE); 664 } else if (zdt.toLocalDate().isBefore(LocalDate.of(1945, 9, 16))) { 665 assertEquals(test.getStandardOffset(instant), OFFSET_ZERO); 666 } else { 667 assertEquals(test.getStandardOffset(instant), OFFSET_PONE); 668 } 669 zdt = zdt.plusMonths(6); 670 } 671 } 672 673 //----------------------------------------------------------------------- 674 // America/New_York 675 //----------------------------------------------------------------------- 676 private ZoneRules americaNewYork() { 677 return ZoneId.of("America/New_York").getRules(); 678 } 679 680 public void test_NewYork() { 681 ZoneRules test = americaNewYork(); 682 assertEquals(test.isFixedOffset(), false); 683 } 684 685 public void test_NewYork_preTimeZones() { 686 ZoneRules test = americaNewYork(); 687 ZonedDateTime old = createZDT(1800, 1, 1, ZoneOffset.UTC); 688 Instant instant = old.toInstant(); 689 ZoneOffset offset = ZoneOffset.of("-04:56:02"); 690 assertEquals(test.getOffset(instant), offset); 691 checkOffset(test, old.toLocalDateTime(), offset, 1); 692 assertEquals(test.getStandardOffset(instant), offset); 693 assertEquals(test.getDaylightSavings(instant), Duration.ZERO); 694 assertEquals(test.isDaylightSavings(instant), false); 695 } 696 697 public void test_NewYork_getOffset() { 698 ZoneRules test = americaNewYork(); 699 ZoneOffset offset = ZoneOffset.ofHours(-5); 700 assertEquals(test.getOffset(createInstant(2008, 1, 1, offset)), ZoneOffset.ofHours(-5)); 701 assertEquals(test.getOffset(createInstant(2008, 2, 1, offset)), ZoneOffset.ofHours(-5)); 702 assertEquals(test.getOffset(createInstant(2008, 3, 1, offset)), ZoneOffset.ofHours(-5)); 703 assertEquals(test.getOffset(createInstant(2008, 4, 1, offset)), ZoneOffset.ofHours(-4)); 704 assertEquals(test.getOffset(createInstant(2008, 5, 1, offset)), ZoneOffset.ofHours(-4)); 705 assertEquals(test.getOffset(createInstant(2008, 6, 1, offset)), ZoneOffset.ofHours(-4)); 706 assertEquals(test.getOffset(createInstant(2008, 7, 1, offset)), ZoneOffset.ofHours(-4)); 707 assertEquals(test.getOffset(createInstant(2008, 8, 1, offset)), ZoneOffset.ofHours(-4)); 708 assertEquals(test.getOffset(createInstant(2008, 9, 1, offset)), ZoneOffset.ofHours(-4)); 709 assertEquals(test.getOffset(createInstant(2008, 10, 1, offset)), ZoneOffset.ofHours(-4)); 710 assertEquals(test.getOffset(createInstant(2008, 11, 1, offset)), ZoneOffset.ofHours(-4)); 711 assertEquals(test.getOffset(createInstant(2008, 12, 1, offset)), ZoneOffset.ofHours(-5)); 712 assertEquals(test.getOffset(createInstant(2008, 1, 28, offset)), ZoneOffset.ofHours(-5)); 713 assertEquals(test.getOffset(createInstant(2008, 2, 28, offset)), ZoneOffset.ofHours(-5)); 714 assertEquals(test.getOffset(createInstant(2008, 3, 28, offset)), ZoneOffset.ofHours(-4)); 715 assertEquals(test.getOffset(createInstant(2008, 4, 28, offset)), ZoneOffset.ofHours(-4)); 716 assertEquals(test.getOffset(createInstant(2008, 5, 28, offset)), ZoneOffset.ofHours(-4)); 717 assertEquals(test.getOffset(createInstant(2008, 6, 28, offset)), ZoneOffset.ofHours(-4)); 718 assertEquals(test.getOffset(createInstant(2008, 7, 28, offset)), ZoneOffset.ofHours(-4)); 719 assertEquals(test.getOffset(createInstant(2008, 8, 28, offset)), ZoneOffset.ofHours(-4)); 720 assertEquals(test.getOffset(createInstant(2008, 9, 28, offset)), ZoneOffset.ofHours(-4)); 721 assertEquals(test.getOffset(createInstant(2008, 10, 28, offset)), ZoneOffset.ofHours(-4)); 722 assertEquals(test.getOffset(createInstant(2008, 11, 28, offset)), ZoneOffset.ofHours(-5)); 723 assertEquals(test.getOffset(createInstant(2008, 12, 28, offset)), ZoneOffset.ofHours(-5)); 724 } 725 726 public void test_NewYork_getOffset_toDST() { 727 ZoneRules test = americaNewYork(); 728 ZoneOffset offset = ZoneOffset.ofHours(-5); 729 assertEquals(test.getOffset(createInstant(2008, 3, 8, offset)), ZoneOffset.ofHours(-5)); 730 assertEquals(test.getOffset(createInstant(2008, 3, 9, offset)), ZoneOffset.ofHours(-5)); 731 assertEquals(test.getOffset(createInstant(2008, 3, 10, offset)), ZoneOffset.ofHours(-4)); 732 assertEquals(test.getOffset(createInstant(2008, 3, 11, offset)), ZoneOffset.ofHours(-4)); 733 assertEquals(test.getOffset(createInstant(2008, 3, 12, offset)), ZoneOffset.ofHours(-4)); 734 assertEquals(test.getOffset(createInstant(2008, 3, 13, offset)), ZoneOffset.ofHours(-4)); 735 assertEquals(test.getOffset(createInstant(2008, 3, 14, offset)), ZoneOffset.ofHours(-4)); 736 // cutover at 02:00 local 737 assertEquals(test.getOffset(createInstant(2008, 3, 9, 1, 59, 59, 999999999, offset)), ZoneOffset.ofHours(-5)); 738 assertEquals(test.getOffset(createInstant(2008, 3, 9, 2, 0, 0, 0, offset)), ZoneOffset.ofHours(-4)); 739 } 740 741 public void test_NewYork_getOffset_fromDST() { 742 ZoneRules test = americaNewYork(); 743 ZoneOffset offset = ZoneOffset.ofHours(-4); 744 assertEquals(test.getOffset(createInstant(2008, 11, 1, offset)), ZoneOffset.ofHours(-4)); 745 assertEquals(test.getOffset(createInstant(2008, 11, 2, offset)), ZoneOffset.ofHours(-4)); 746 assertEquals(test.getOffset(createInstant(2008, 11, 3, offset)), ZoneOffset.ofHours(-5)); 747 assertEquals(test.getOffset(createInstant(2008, 11, 4, offset)), ZoneOffset.ofHours(-5)); 748 assertEquals(test.getOffset(createInstant(2008, 11, 5, offset)), ZoneOffset.ofHours(-5)); 749 assertEquals(test.getOffset(createInstant(2008, 11, 6, offset)), ZoneOffset.ofHours(-5)); 750 assertEquals(test.getOffset(createInstant(2008, 11, 7, offset)), ZoneOffset.ofHours(-5)); 751 // cutover at 02:00 local 752 assertEquals(test.getOffset(createInstant(2008, 11, 2, 1, 59, 59, 999999999, offset)), ZoneOffset.ofHours(-4)); 753 assertEquals(test.getOffset(createInstant(2008, 11, 2, 2, 0, 0, 0, offset)), ZoneOffset.ofHours(-5)); 754 } 755 756 public void test_NewYork_getOffsetInfo() { 757 ZoneRules test = americaNewYork(); 758 checkOffset(test, createLDT(2008, 1, 1), ZoneOffset.ofHours(-5), 1); 759 checkOffset(test, createLDT(2008, 2, 1), ZoneOffset.ofHours(-5), 1); 760 checkOffset(test, createLDT(2008, 3, 1), ZoneOffset.ofHours(-5), 1); 761 checkOffset(test, createLDT(2008, 4, 1), ZoneOffset.ofHours(-4), 1); 762 checkOffset(test, createLDT(2008, 5, 1), ZoneOffset.ofHours(-4), 1); 763 checkOffset(test, createLDT(2008, 6, 1), ZoneOffset.ofHours(-4), 1); 764 checkOffset(test, createLDT(2008, 7, 1), ZoneOffset.ofHours(-4), 1); 765 checkOffset(test, createLDT(2008, 8, 1), ZoneOffset.ofHours(-4), 1); 766 checkOffset(test, createLDT(2008, 9, 1), ZoneOffset.ofHours(-4), 1); 767 checkOffset(test, createLDT(2008, 10, 1), ZoneOffset.ofHours(-4), 1); 768 checkOffset(test, createLDT(2008, 11, 1), ZoneOffset.ofHours(-4), 1); 769 checkOffset(test, createLDT(2008, 12, 1), ZoneOffset.ofHours(-5), 1); 770 checkOffset(test, createLDT(2008, 1, 28), ZoneOffset.ofHours(-5), 1); 771 checkOffset(test, createLDT(2008, 2, 28), ZoneOffset.ofHours(-5), 1); 772 checkOffset(test, createLDT(2008, 3, 28), ZoneOffset.ofHours(-4), 1); 773 checkOffset(test, createLDT(2008, 4, 28), ZoneOffset.ofHours(-4), 1); 774 checkOffset(test, createLDT(2008, 5, 28), ZoneOffset.ofHours(-4), 1); 775 checkOffset(test, createLDT(2008, 6, 28), ZoneOffset.ofHours(-4), 1); 776 checkOffset(test, createLDT(2008, 7, 28), ZoneOffset.ofHours(-4), 1); 777 checkOffset(test, createLDT(2008, 8, 28), ZoneOffset.ofHours(-4), 1); 778 checkOffset(test, createLDT(2008, 9, 28), ZoneOffset.ofHours(-4), 1); 779 checkOffset(test, createLDT(2008, 10, 28), ZoneOffset.ofHours(-4), 1); 780 checkOffset(test, createLDT(2008, 11, 28), ZoneOffset.ofHours(-5), 1); 781 checkOffset(test, createLDT(2008, 12, 28), ZoneOffset.ofHours(-5), 1); 782 } 783 784 public void test_NewYork_getOffsetInfo_toDST() { 785 ZoneRules test = americaNewYork(); 786 checkOffset(test, createLDT(2008, 3, 8), ZoneOffset.ofHours(-5), 1); 787 checkOffset(test, createLDT(2008, 3, 9), ZoneOffset.ofHours(-5), 1); 788 checkOffset(test, createLDT(2008, 3, 10), ZoneOffset.ofHours(-4), 1); 789 checkOffset(test, createLDT(2008, 3, 11), ZoneOffset.ofHours(-4), 1); 790 checkOffset(test, createLDT(2008, 3, 12), ZoneOffset.ofHours(-4), 1); 791 checkOffset(test, createLDT(2008, 3, 13), ZoneOffset.ofHours(-4), 1); 792 checkOffset(test, createLDT(2008, 3, 14), ZoneOffset.ofHours(-4), 1); 793 // cutover at 02:00 local 794 checkOffset(test, LocalDateTime.of(2008, 3, 9, 1, 59, 59, 999999999), ZoneOffset.ofHours(-5), 1); 795 checkOffset(test, LocalDateTime.of(2008, 3, 9, 3, 0, 0, 0), ZoneOffset.ofHours(-4), 1); 796 } 797 798 public void test_NewYork_getOffsetInfo_fromDST() { 799 ZoneRules test = americaNewYork(); 800 checkOffset(test, createLDT(2008, 11, 1), ZoneOffset.ofHours(-4), 1); 801 checkOffset(test, createLDT(2008, 11, 2), ZoneOffset.ofHours(-4), 1); 802 checkOffset(test, createLDT(2008, 11, 3), ZoneOffset.ofHours(-5), 1); 803 checkOffset(test, createLDT(2008, 11, 4), ZoneOffset.ofHours(-5), 1); 804 checkOffset(test, createLDT(2008, 11, 5), ZoneOffset.ofHours(-5), 1); 805 checkOffset(test, createLDT(2008, 11, 6), ZoneOffset.ofHours(-5), 1); 806 checkOffset(test, createLDT(2008, 11, 7), ZoneOffset.ofHours(-5), 1); 807 // cutover at 02:00 local 808 checkOffset(test, LocalDateTime.of(2008, 11, 2, 0, 59, 59, 999999999), ZoneOffset.ofHours(-4), 1); 809 checkOffset(test, LocalDateTime.of(2008, 11, 2, 2, 0, 0, 0), ZoneOffset.ofHours(-5), 1); 810 } 811 812 public void test_NewYork_getOffsetInfo_gap() { 813 ZoneRules test = americaNewYork(); 814 final LocalDateTime dateTime = LocalDateTime.of(2008, 3, 9, 2, 0, 0, 0); 815 ZoneOffsetTransition trans = checkOffset(test, dateTime, ZoneOffset.ofHours(-5), GAP); 816 assertEquals(trans.isGap(), true); 817 assertEquals(trans.isOverlap(), false); 818 assertEquals(trans.getOffsetBefore(), ZoneOffset.ofHours(-5)); 819 assertEquals(trans.getOffsetAfter(), ZoneOffset.ofHours(-4)); 820 assertEquals(trans.getInstant(), createInstant(2008, 3, 9, 2, 0, ZoneOffset.ofHours(-5))); 821 assertEquals(trans.isValidOffset(OFFSET_PTWO), false); 822 assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-5)), false); 823 assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-4)), false); 824 assertEquals(trans.toString(), "Transition[Gap at 2008-03-09T02:00-05:00 to -04:00]"); 825 826 assertFalse(trans.equals(null)); 827 assertFalse(trans.equals(ZoneOffset.ofHours(-5))); 828 assertTrue(trans.equals(trans)); 829 830 final ZoneOffsetTransition otherTrans = test.getTransition(dateTime); 831 assertTrue(trans.equals(otherTrans)); 832 assertEquals(trans.hashCode(), otherTrans.hashCode()); 833 } 834 835 public void test_NewYork_getOffsetInfo_overlap() { 836 ZoneRules test = americaNewYork(); 837 final LocalDateTime dateTime = LocalDateTime.of(2008, 11, 2, 1, 0, 0, 0); 838 ZoneOffsetTransition trans = checkOffset(test, dateTime, ZoneOffset.ofHours(-4), OVERLAP); 839 assertEquals(trans.isGap(), false); 840 assertEquals(trans.isOverlap(), true); 841 assertEquals(trans.getOffsetBefore(), ZoneOffset.ofHours(-4)); 842 assertEquals(trans.getOffsetAfter(), ZoneOffset.ofHours(-5)); 843 assertEquals(trans.getInstant(), createInstant(2008, 11, 2, 2, 0, ZoneOffset.ofHours(-4))); 844 assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-1)), false); 845 assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-5)), true); 846 assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-4)), true); 847 assertEquals(trans.isValidOffset(OFFSET_PTWO), false); 848 assertEquals(trans.toString(), "Transition[Overlap at 2008-11-02T02:00-04:00 to -05:00]"); 849 850 assertFalse(trans.equals(null)); 851 assertFalse(trans.equals(ZoneOffset.ofHours(-4))); 852 assertTrue(trans.equals(trans)); 853 854 final ZoneOffsetTransition otherTrans = test.getTransition(dateTime); 855 assertTrue(trans.equals(otherTrans)); 856 assertEquals(trans.hashCode(), otherTrans.hashCode()); 857 } 858 859 public void test_NewYork_getStandardOffset() { 860 ZoneRules test = americaNewYork(); 861 ZonedDateTime dateTime = createZDT(1860, 1, 1, ZoneOffset.UTC); 862 while (dateTime.getYear() < 2010) { 863 Instant instant = dateTime.toInstant(); 864 if (dateTime.toLocalDate().isBefore(LocalDate.of(1883, 11, 18))) { 865 assertEquals(test.getStandardOffset(instant), ZoneOffset.of("-04:56:02")); 866 } else { 867 assertEquals(test.getStandardOffset(instant), ZoneOffset.ofHours(-5)); 868 } 869 dateTime = dateTime.plusMonths(6); 870 } 871 } 872 873 //----------------------------------------------------------------------- 874 // Kathmandu 875 //----------------------------------------------------------------------- 876 private ZoneRules asiaKathmandu() { 877 return ZoneId.of("Asia/Kathmandu").getRules(); 878 } 879 880 public void test_Kathmandu_nextTransition_historic() { 881 ZoneRules test = asiaKathmandu(); 882 List<ZoneOffsetTransition> trans = test.getTransitions(); 883 884 ZoneOffsetTransition first = trans.get(0); 885 assertEquals(test.nextTransition(first.getInstant().minusNanos(1)), first); 886 887 for (int i = 0; i < trans.size() - 1; i++) { 888 ZoneOffsetTransition cur = trans.get(i); 889 ZoneOffsetTransition next = trans.get(i + 1); 890 891 assertEquals(test.nextTransition(cur.getInstant()), next); 892 assertEquals(test.nextTransition(next.getInstant().minusNanos(1)), next); 893 } 894 } 895 896 public void test_Kathmandu_nextTransition_noRules() { 897 ZoneRules test = asiaKathmandu(); 898 List<ZoneOffsetTransition> trans = test.getTransitions(); 899 900 ZoneOffsetTransition last = trans.get(trans.size() - 1); 901 assertEquals(test.nextTransition(last.getInstant()), null); 902 } 903 904 //----------------------------------------------------------------------- 905 // Apia 906 //----------------------------------------------------------------------- 907 private ZoneRules pacificApia() { 908 return ZoneId.of("Pacific/Apia").getRules(); 909 } 910 911 public void test_Apia_nextTransition_historic() { 912 ZoneRules test = pacificApia(); 913 List<ZoneOffsetTransition> trans = test.getTransitions(); 914 915 ZoneOffsetTransition first = trans.get(0); 916 assertEquals(test.nextTransition(first.getInstant().minusNanos(1)), first); 917 918 for (int i = 0; i < trans.size() - 1; i++) { 919 ZoneOffsetTransition cur = trans.get(i); 920 ZoneOffsetTransition next = trans.get(i + 1); 921 922 assertEquals(test.nextTransition(cur.getInstant()), next); 923 assertEquals(test.nextTransition(next.getInstant().minusNanos(1)), next); 924 } 925 } 926 927 public void test_Apia_jumpOverInternationalDateLine_M10_to_P14() { 928 // transition occurred at 2011-12-30T00:00-10:00 929 ZoneRules test = pacificApia(); 930 Instant instantBefore = LocalDate.of(2011, 12, 27).atStartOfDay(ZoneOffset.UTC).toInstant(); 931 ZoneOffsetTransition trans = test.nextTransition(instantBefore); 932 assertEquals(trans.getDateTimeBefore(), LocalDateTime.of(2011, 12, 30, 0, 0)); 933 assertEquals(trans.getDateTimeAfter(), LocalDateTime.of(2011, 12, 31, 0, 0)); 934 assertEquals(trans.isGap(), true); 935 assertEquals(trans.isOverlap(), false); 936 assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-10)), false); 937 assertEquals(trans.isValidOffset(ZoneOffset.ofHours(+14)), false); 938 assertEquals(trans.getDuration(), Duration.ofHours(24)); 939 assertEquals(trans.getInstant(), LocalDateTime.of(2011, 12, 31, 0, 0).toInstant(ZoneOffset.ofHours(+14))); 940 941 ZonedDateTime zdt = ZonedDateTime.of(2011, 12, 29, 23, 0, 0, 0, ZoneId.of("Pacific/Apia")); 942 assertEquals(zdt.plusHours(2).toLocalDateTime(), LocalDateTime.of(2011, 12, 31, 1, 0)); 943 } 944 945 public void test_Apia_jumpForwardOverInternationalDateLine_P12_to_M12() { 946 // Android-changed: 1879 changed to 1892 in this test due to 2017c IANA update. Upstream 947 // will probably do the same. See https://bugs.openjdk.java.net/browse/JDK-8190259 948 // transition occurred at 1892-07-04T00:00+12:33:04 949 ZoneRules test = pacificApia(); 950 Instant instantBefore = LocalDate.of(1892, 7, 2).atStartOfDay(ZoneOffset.UTC).toInstant(); 951 ZoneOffsetTransition trans = test.nextTransition(instantBefore); 952 assertEquals(trans.getDateTimeBefore(), LocalDateTime.of(1892, 7, 5, 0, 0)); 953 assertEquals(trans.getDateTimeAfter(), LocalDateTime.of(1892, 7, 4, 0, 0)); 954 assertEquals(trans.isGap(), false); 955 assertEquals(trans.isOverlap(), true); 956 assertEquals(trans.isValidOffset(ZoneOffset.ofHoursMinutesSeconds(+12, 33, 4)), true); 957 assertEquals(trans.isValidOffset(ZoneOffset.ofHoursMinutesSeconds(-11, -26, -56)), true); 958 assertEquals(trans.getDuration(), Duration.ofHours(-24)); 959 assertEquals(trans.getInstant(), LocalDateTime.of(1892, 7, 4, 0, 0).toInstant(ZoneOffset.ofHoursMinutesSeconds(-11, -26, -56))); 960 961 ZonedDateTime zdt = ZonedDateTime.of(1892, 7, 4, 23, 0, 0, 0, ZoneId.of("Pacific/Apia")); 962 assertEquals(zdt.plusHours(2).toLocalDateTime(), LocalDateTime.of(1892, 7, 4, 1, 0, 0)); 963 } 964 965 //------------------------------------------------------------------------- 966 @Test(expectedExceptions=UnsupportedOperationException.class) 967 public void test_getTransitions_immutable() { 968 ZoneRules test = europeParis(); 969 test.getTransitions().clear(); 970 } 971 972 @Test(expectedExceptions=UnsupportedOperationException.class) 973 public void test_getTransitionRules_immutable() { 974 ZoneRules test = europeParis(); 975 test.getTransitionRules().clear(); 976 } 977 978 //----------------------------------------------------------------------- 979 // of() 980 //----------------------------------------------------------------------- 981 public void test_of(){ 982 //used for standard offset 983 ZoneOffset stdOffset1 = ZoneOffset.UTC; 984 ZoneOffset stdOffset2 = ZoneOffset.ofHours(1); 985 LocalDateTime time_of_stdOffsetTransition1 = LocalDateTime.of(2013, 1, 5, 1, 0); 986 ZoneOffsetTransition stdOffsetTransition1 = ZoneOffsetTransition.of(time_of_stdOffsetTransition1, stdOffset1, stdOffset2); 987 List<ZoneOffsetTransition> stdOffsetTransition_list = new ArrayList<ZoneOffsetTransition>(); 988 stdOffsetTransition_list.add(stdOffsetTransition1); 989 990 //used for wall offset 991 ZoneOffset wallOffset1 = ZoneOffset.ofHours(2); 992 ZoneOffset wallOffset2 = ZoneOffset.ofHours(4); 993 ZoneOffset wallOffset3 = ZoneOffset.ofHours(7); 994 995 LocalDateTime time_of_wallOffsetTransition1 = LocalDateTime.of(2013, 2, 5, 1, 0); 996 LocalDateTime time_of_wallOffsetTransition2 = LocalDateTime.of(2013, 3, 5, 1, 0); 997 LocalDateTime time_of_wallOffsetTransition3 = LocalDateTime.of(2013, 10, 5, 1, 0); 998 999 ZoneOffsetTransition wallOffsetTransition1 = ZoneOffsetTransition.of(time_of_wallOffsetTransition1, wallOffset1, wallOffset2); 1000 ZoneOffsetTransition wallOffsetTransition2 = ZoneOffsetTransition.of(time_of_wallOffsetTransition2, wallOffset2, wallOffset3); 1001 ZoneOffsetTransition wallOffsetTransition3 = ZoneOffsetTransition.of(time_of_wallOffsetTransition3, wallOffset3, wallOffset1); 1002 1003 List<ZoneOffsetTransition> wallOffsetTransition_list = new ArrayList<ZoneOffsetTransition>(); 1004 wallOffsetTransition_list.add(wallOffsetTransition1); 1005 wallOffsetTransition_list.add(wallOffsetTransition2); 1006 wallOffsetTransition_list.add(wallOffsetTransition3); 1007 1008 //used for ZoneOffsetTransitionRule 1009 ZoneOffset ruleOffset = ZoneOffset.ofHours(3); 1010 ZoneOffsetTransitionRule.TimeDefinition timeDefinition = ZoneOffsetTransitionRule.TimeDefinition.valueOf("WALL"); 1011 ZoneOffsetTransitionRule rule1 = ZoneOffsetTransitionRule.of(Month.FEBRUARY, 1012 2, 1013 DayOfWeek.MONDAY, 1014 LocalTime.of(1, 0), 1015 false, 1016 timeDefinition, 1017 ZoneOffset.UTC, 1018 ZoneOffset.UTC, 1019 ruleOffset 1020 ); 1021 List<ZoneOffsetTransitionRule> rule_list = new ArrayList<ZoneOffsetTransitionRule>(); 1022 rule_list.add(rule1); 1023 1024 //Begin verification 1025 ZoneRules zoneRule = ZoneRules.of(stdOffset1, 1026 wallOffset1, 1027 stdOffsetTransition_list, 1028 wallOffsetTransition_list, 1029 rule_list 1030 ); 1031 1032 OffsetDateTime before_time_of_stdOffsetTransition1 = OffsetDateTime.of(time_of_stdOffsetTransition1, stdOffset1).minusSeconds(1); 1033 OffsetDateTime after_time_of_stdOffsetTransition1 = OffsetDateTime.of(time_of_stdOffsetTransition1, stdOffset1).plusSeconds(1);; 1034 assertEquals(zoneRule.getStandardOffset(before_time_of_stdOffsetTransition1.toInstant()), stdOffset1); 1035 assertEquals(zoneRule.getStandardOffset(after_time_of_stdOffsetTransition1.toInstant()), stdOffset2); 1036 1037 OffsetDateTime before_time_of_wallOffsetTransition1 = OffsetDateTime.of(time_of_wallOffsetTransition1, wallOffset1).minusSeconds(1); 1038 OffsetDateTime after_time_of_wallOffsetTransition1 = OffsetDateTime.of(time_of_wallOffsetTransition1, wallOffset1).plusSeconds(1); 1039 assertEquals(zoneRule.nextTransition(before_time_of_wallOffsetTransition1.toInstant()), wallOffsetTransition1); 1040 assertEquals(zoneRule.nextTransition(after_time_of_wallOffsetTransition1.toInstant()), wallOffsetTransition2); 1041 1042 OffsetDateTime before_time_of_wallOffsetTransition2 = OffsetDateTime.of(time_of_wallOffsetTransition2, wallOffset2).minusSeconds(1); 1043 OffsetDateTime after_time_of_wallOffsetTransition2 = OffsetDateTime.of(time_of_wallOffsetTransition2, wallOffset2).plusSeconds(1); 1044 assertEquals(zoneRule.nextTransition(before_time_of_wallOffsetTransition2.toInstant()), wallOffsetTransition2); 1045 assertEquals(zoneRule.nextTransition(after_time_of_wallOffsetTransition2.toInstant()), wallOffsetTransition3); 1046 1047 OffsetDateTime before_time_of_wallOffsetTransition3 = OffsetDateTime.of(time_of_wallOffsetTransition3, wallOffset3).minusSeconds(1); 1048 OffsetDateTime after_time_of_wallOffsetTransition3 = OffsetDateTime.of(time_of_wallOffsetTransition3, wallOffset3).plusSeconds(1); 1049 assertEquals(zoneRule.nextTransition(before_time_of_wallOffsetTransition3.toInstant()), wallOffsetTransition3); 1050 assertEquals(zoneRule.nextTransition(after_time_of_wallOffsetTransition3.toInstant()), rule1.createTransition(2014)); 1051 } 1052 1053 //----------------------------------------------------------------------- 1054 // equals() / hashCode() 1055 //----------------------------------------------------------------------- 1056 public void test_equals() { 1057 ZoneRules test1 = europeLondon(); 1058 ZoneRules test2 = europeParis(); 1059 ZoneRules test2b = europeParis(); 1060 assertEquals(test1.equals(test2), false); 1061 assertEquals(test2.equals(test1), false); 1062 1063 assertEquals(test1.equals(test1), true); 1064 assertEquals(test2.equals(test2), true); 1065 assertEquals(test2.equals(test2b), true); 1066 1067 assertEquals(test1.hashCode() == test1.hashCode(), true); 1068 assertEquals(test2.hashCode() == test2.hashCode(), true); 1069 assertEquals(test2.hashCode() == test2b.hashCode(), true); 1070 } 1071 1072 public void test_equals_null() { 1073 assertEquals(europeLondon().equals(null), false); 1074 } 1075 1076 public void test_equals_notZoneRules() { 1077 assertEquals(europeLondon().equals("Europe/London"), false); 1078 } 1079 1080 public void test_toString() { 1081 assertEquals(europeLondon().toString().contains("ZoneRules"), true); 1082 } 1083 1084 //----------------------------------------------------------------------- 1085 //----------------------------------------------------------------------- 1086 //----------------------------------------------------------------------- 1087 private Instant createInstant(int year, int month, int day, ZoneOffset offset) { 1088 return LocalDateTime.of(year, month, day, 0, 0).toInstant(offset); 1089 } 1090 1091 private Instant createInstant(int year, int month, int day, int hour, int min, ZoneOffset offset) { 1092 return LocalDateTime.of(year, month, day, hour, min).toInstant(offset); 1093 } 1094 1095 private Instant createInstant(int year, int month, int day, int hour, int min, int sec, int nano, ZoneOffset offset) { 1096 return LocalDateTime.of(year, month, day, hour, min, sec, nano).toInstant(offset); 1097 } 1098 1099 private ZonedDateTime createZDT(int year, int month, int day, ZoneId zone) { 1100 return LocalDateTime.of(year, month, day, 0, 0).atZone(zone); 1101 } 1102 1103 private LocalDateTime createLDT(int year, int month, int day) { 1104 return LocalDateTime.of(year, month, day, 0, 0); 1105 } 1106 1107 private ZoneOffsetTransition checkOffset(ZoneRules rules, LocalDateTime dateTime, ZoneOffset offset, int type) { 1108 List<ZoneOffset> validOffsets = rules.getValidOffsets(dateTime); 1109 assertEquals(validOffsets.size(), type); 1110 assertEquals(rules.getOffset(dateTime), offset); 1111 if (type == 1) { 1112 assertEquals(validOffsets.get(0), offset); 1113 return null; 1114 } else { 1115 ZoneOffsetTransition zot = rules.getTransition(dateTime); 1116 assertNotNull(zot); 1117 assertEquals(zot.isOverlap(), type == 2); 1118 assertEquals(zot.isGap(), type == 0); 1119 assertEquals(zot.isValidOffset(offset), type == 2); 1120 return zot; 1121 } 1122 } 1123 1124} 1125