1 /*
   2  * Copyright (c) 2012, 2015, 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  */
  60 package tck.java.time;
  61 
  62 import static java.time.Month.JANUARY;
  63 import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH;
  64 import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR;
  65 import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_MONTH;
  66 import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_YEAR;
  67 import static java.time.temporal.ChronoField.AMPM_OF_DAY;
  68 import static java.time.temporal.ChronoField.CLOCK_HOUR_OF_AMPM;
  69 import static java.time.temporal.ChronoField.CLOCK_HOUR_OF_DAY;
  70 import static java.time.temporal.ChronoField.DAY_OF_MONTH;
  71 import static java.time.temporal.ChronoField.DAY_OF_WEEK;
  72 import static java.time.temporal.ChronoField.DAY_OF_YEAR;
  73 import static java.time.temporal.ChronoField.EPOCH_DAY;
  74 import static java.time.temporal.ChronoField.ERA;
  75 import static java.time.temporal.ChronoField.HOUR_OF_AMPM;
  76 import static java.time.temporal.ChronoField.HOUR_OF_DAY;
  77 import static java.time.temporal.ChronoField.INSTANT_SECONDS;
  78 import static java.time.temporal.ChronoField.MICRO_OF_DAY;
  79 import static java.time.temporal.ChronoField.MICRO_OF_SECOND;
  80 import static java.time.temporal.ChronoField.MILLI_OF_DAY;
  81 import static java.time.temporal.ChronoField.MILLI_OF_SECOND;
  82 import static java.time.temporal.ChronoField.MINUTE_OF_DAY;
  83 import static java.time.temporal.ChronoField.MINUTE_OF_HOUR;
  84 import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
  85 import static java.time.temporal.ChronoField.NANO_OF_DAY;
  86 import static java.time.temporal.ChronoField.NANO_OF_SECOND;
  87 import static java.time.temporal.ChronoField.OFFSET_SECONDS;
  88 import static java.time.temporal.ChronoField.PROLEPTIC_MONTH;
  89 import static java.time.temporal.ChronoField.SECOND_OF_DAY;
  90 import static java.time.temporal.ChronoField.SECOND_OF_MINUTE;
  91 import static java.time.temporal.ChronoField.YEAR;
  92 import static java.time.temporal.ChronoField.YEAR_OF_ERA;
  93 import static java.time.temporal.ChronoUnit.DAYS;
  94 import static java.time.temporal.ChronoUnit.HOURS;
  95 import static java.time.temporal.ChronoUnit.MINUTES;
  96 import static java.time.temporal.ChronoUnit.NANOS;
  97 import static java.time.temporal.ChronoUnit.SECONDS;
  98 import static org.testng.Assert.assertEquals;
  99 import static org.testng.Assert.assertTrue;
 100 
 101 import java.io.ByteArrayOutputStream;
 102 import java.io.DataOutputStream;
 103 import java.io.IOException;
 104 import java.time.Clock;
 105 import java.time.DateTimeException;
 106 import java.time.Duration;
 107 import java.time.Instant;
 108 import java.time.LocalDate;
 109 import java.time.LocalDateTime;
 110 import java.time.LocalTime;
 111 import java.time.Month;
 112 import java.time.OffsetDateTime;
 113 import java.time.OffsetTime;
 114 import java.time.Period;
 115 import java.time.Year;
 116 import java.time.ZoneId;
 117 import java.time.ZoneOffset;
 118 import java.time.ZonedDateTime;
 119 import java.time.chrono.IsoChronology;
 120 import java.time.format.DateTimeFormatter;
 121 import java.time.format.DateTimeParseException;
 122 import java.time.temporal.ChronoField;
 123 import java.time.temporal.ChronoUnit;
 124 import java.time.temporal.JulianFields;
 125 import java.time.temporal.TemporalAccessor;
 126 import java.time.temporal.TemporalAdjuster;
 127 import java.time.temporal.TemporalAmount;
 128 import java.time.temporal.TemporalField;
 129 import java.time.temporal.TemporalQueries;
 130 import java.time.temporal.TemporalQuery;
 131 import java.time.temporal.TemporalUnit;
 132 import java.util.ArrayList;
 133 import java.util.Arrays;
 134 import java.util.List;
 135 
 136 import org.testng.annotations.BeforeMethod;
 137 import org.testng.annotations.DataProvider;
 138 import org.testng.annotations.Test;
 139 
 140 /**
 141  * Test ZonedDateTime.
 142  */
 143 @Test
 144 public class TCKZonedDateTime extends AbstractDateTimeTest {
 145 
 146     private static final ZoneOffset OFFSET_0100 = ZoneOffset.ofHours(1);
 147     private static final ZoneOffset OFFSET_0200 = ZoneOffset.ofHours(2);
 148     private static final ZoneOffset OFFSET_0130 = ZoneOffset.of("+01:30");
 149     private static final ZoneOffset OFFSET_MAX = ZoneOffset.MAX;
 150     private static final ZoneOffset OFFSET_MIN = ZoneOffset.MIN;
 151 
 152     private static final ZoneId ZONE_0100 = OFFSET_0100;
 153     private static final ZoneId ZONE_0200 = OFFSET_0200;
 154     private static final ZoneId ZONE_M0100 = ZoneOffset.ofHours(-1);
 155     private static final ZoneId ZONE_LONDON = ZoneId.of("Europe/London");
 156     private static final ZoneId ZONE_PARIS = ZoneId.of("Europe/Paris");
 157     private LocalDateTime TEST_PARIS_GAP_2008_03_30_02_30;
 158     private LocalDateTime TEST_PARIS_OVERLAP_2008_10_26_02_30;
 159     private LocalDateTime TEST_LOCAL_2008_06_30_11_30_59_500;
 160     private ZonedDateTime TEST_DATE_TIME;
 161     private ZonedDateTime TEST_DATE_TIME_PARIS;
 162 
 163     @BeforeMethod
 164     public void setUp() {
 165         TEST_LOCAL_2008_06_30_11_30_59_500 = LocalDateTime.of(2008, 6, 30, 11, 30, 59, 500);
 166         TEST_DATE_TIME = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
 167         TEST_DATE_TIME_PARIS = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_PARIS);
 168         TEST_PARIS_OVERLAP_2008_10_26_02_30 = LocalDateTime.of(2008, 10, 26, 2, 30);
 169         TEST_PARIS_GAP_2008_03_30_02_30 = LocalDateTime.of(2008, 3, 30, 2, 30);
 170     }
 171 
 172     //-----------------------------------------------------------------------
 173     @Override
 174     protected List<TemporalAccessor> samples() {
 175         TemporalAccessor[] array = {TEST_DATE_TIME, };
 176         return Arrays.asList(array);
 177     }
 178 
 179     @Override
 180     protected List<TemporalField> validFields() {
 181         TemporalField[] array = {
 182             NANO_OF_SECOND,
 183             NANO_OF_DAY,
 184             MICRO_OF_SECOND,
 185             MICRO_OF_DAY,
 186             MILLI_OF_SECOND,
 187             MILLI_OF_DAY,
 188             SECOND_OF_MINUTE,
 189             SECOND_OF_DAY,
 190             MINUTE_OF_HOUR,
 191             MINUTE_OF_DAY,
 192             CLOCK_HOUR_OF_AMPM,
 193             HOUR_OF_AMPM,
 194             CLOCK_HOUR_OF_DAY,
 195             HOUR_OF_DAY,
 196             AMPM_OF_DAY,
 197             DAY_OF_WEEK,
 198             ALIGNED_DAY_OF_WEEK_IN_MONTH,
 199             ALIGNED_DAY_OF_WEEK_IN_YEAR,
 200             DAY_OF_MONTH,
 201             DAY_OF_YEAR,
 202             EPOCH_DAY,
 203             ALIGNED_WEEK_OF_MONTH,
 204             ALIGNED_WEEK_OF_YEAR,
 205             MONTH_OF_YEAR,
 206             PROLEPTIC_MONTH,
 207             YEAR_OF_ERA,
 208             YEAR,
 209             ERA,
 210             OFFSET_SECONDS,
 211             INSTANT_SECONDS,
 212             JulianFields.JULIAN_DAY,
 213             JulianFields.MODIFIED_JULIAN_DAY,
 214             JulianFields.RATA_DIE,
 215         };
 216         return Arrays.asList(array);
 217     }
 218 
 219     @Override
 220     protected List<TemporalField> invalidFields() {
 221         List<TemporalField> list = new ArrayList<>(Arrays.<TemporalField>asList(ChronoField.values()));
 222         list.removeAll(validFields());
 223         return list;
 224     }
 225 
 226     //-----------------------------------------------------------------------
 227     // now()
 228     //-----------------------------------------------------------------------
 229     @Test
 230     public void now() {
 231         ZonedDateTime expected = ZonedDateTime.now(Clock.systemDefaultZone());
 232         ZonedDateTime test = ZonedDateTime.now();
 233         long diff = Math.abs(test.toLocalTime().toNanoOfDay() - expected.toLocalTime().toNanoOfDay());
 234         if (diff >= 100000000) {
 235             // may be date change
 236             expected = ZonedDateTime.now(Clock.systemDefaultZone());
 237             test = ZonedDateTime.now();
 238             diff = Math.abs(test.toLocalTime().toNanoOfDay() - expected.toLocalTime().toNanoOfDay());
 239         }
 240         assertTrue(diff < 100000000);  // less than 0.1 secs
 241     }
 242 
 243     //-----------------------------------------------------------------------
 244     // now(ZoneId)
 245     //-----------------------------------------------------------------------
 246     @Test(expectedExceptions=NullPointerException.class)
 247     public void now_ZoneId_nullZoneId() {
 248         ZonedDateTime.now((ZoneId) null);
 249     }
 250 
 251     @Test
 252     public void now_ZoneId() {
 253         ZoneId zone = ZoneId.of("UTC+01:02:03");
 254         ZonedDateTime expected = ZonedDateTime.now(Clock.system(zone));
 255         ZonedDateTime test = ZonedDateTime.now(zone);
 256         for (int i = 0; i < 100; i++) {
 257             if (expected.equals(test)) {
 258                 return;
 259             }
 260             expected = ZonedDateTime.now(Clock.system(zone));
 261             test = ZonedDateTime.now(zone);
 262         }
 263         assertEquals(test.truncatedTo(ChronoUnit.SECONDS),
 264                      expected.truncatedTo(ChronoUnit.SECONDS));
 265     }
 266 
 267     //-----------------------------------------------------------------------
 268     // now(Clock)
 269     //-----------------------------------------------------------------------
 270     @Test(expectedExceptions=NullPointerException.class)
 271     public void now_Clock_nullClock() {
 272         ZonedDateTime.now((Clock) null);
 273     }
 274 
 275     @Test
 276     public void now_Clock_allSecsInDay_utc() {
 277         for (int i = 0; i < (2 * 24 * 60 * 60); i++) {
 278             Instant instant = Instant.ofEpochSecond(i).plusNanos(123456789L);
 279             Clock clock = Clock.fixed(instant, ZoneOffset.UTC);
 280             ZonedDateTime test = ZonedDateTime.now(clock);
 281             assertEquals(test.getYear(), 1970);
 282             assertEquals(test.getMonth(), Month.JANUARY);
 283             assertEquals(test.getDayOfMonth(), (i < 24 * 60 * 60 ? 1 : 2));
 284             assertEquals(test.getHour(), (i / (60 * 60)) % 24);
 285             assertEquals(test.getMinute(), (i / 60) % 60);
 286             assertEquals(test.getSecond(), i % 60);
 287             assertEquals(test.getNano(), 123456789);
 288             assertEquals(test.getOffset(), ZoneOffset.UTC);
 289             assertEquals(test.getZone(), ZoneOffset.UTC);
 290         }
 291     }
 292 
 293     @Test
 294     public void now_Clock_allSecsInDay_zone() {
 295         ZoneId zone = ZoneId.of("Europe/London");
 296         for (int i = 0; i < (2 * 24 * 60 * 60); i++) {
 297             Instant instant = Instant.ofEpochSecond(i).plusNanos(123456789L);
 298             ZonedDateTime expected = ZonedDateTime.ofInstant(instant, zone);
 299             Clock clock = Clock.fixed(expected.toInstant(), zone);
 300             ZonedDateTime test = ZonedDateTime.now(clock);
 301             assertEquals(test, expected);
 302         }
 303     }
 304 
 305     @Test
 306     public void now_Clock_allSecsInDay_beforeEpoch() {
 307         LocalTime expected = LocalTime.MIDNIGHT.plusNanos(123456789L);
 308         for (int i =-1; i >= -(24 * 60 * 60); i--) {
 309             Instant instant = Instant.ofEpochSecond(i).plusNanos(123456789L);
 310             Clock clock = Clock.fixed(instant, ZoneOffset.UTC);
 311             ZonedDateTime test = ZonedDateTime.now(clock);
 312             assertEquals(test.getYear(), 1969);
 313             assertEquals(test.getMonth(), Month.DECEMBER);
 314             assertEquals(test.getDayOfMonth(), 31);
 315             expected = expected.minusSeconds(1);
 316             assertEquals(test.toLocalTime(), expected);
 317             assertEquals(test.getOffset(), ZoneOffset.UTC);
 318             assertEquals(test.getZone(), ZoneOffset.UTC);
 319         }
 320     }
 321 
 322     @Test
 323     public void now_Clock_offsets() {
 324         ZonedDateTime base = ZonedDateTime.of(LocalDateTime.of(1970, 1, 1, 12, 0), ZoneOffset.UTC);
 325         for (int i = -9; i < 15; i++) {
 326             ZoneOffset offset = ZoneOffset.ofHours(i);
 327             Clock clock = Clock.fixed(base.toInstant(), offset);
 328             ZonedDateTime test = ZonedDateTime.now(clock);
 329             assertEquals(test.getHour(), (12 + i) % 24);
 330             assertEquals(test.getMinute(), 0);
 331             assertEquals(test.getSecond(), 0);
 332             assertEquals(test.getNano(), 0);
 333             assertEquals(test.getOffset(), offset);
 334             assertEquals(test.getZone(), offset);
 335         }
 336     }
 337 
 338     //-----------------------------------------------------------------------
 339     // dateTime factories
 340     //-----------------------------------------------------------------------
 341     void check(ZonedDateTime test, int y, int m, int d, int h, int min, int s, int n, ZoneOffset offset, ZoneId zone) {
 342         assertEquals(test.getYear(), y);
 343         assertEquals(test.getMonth().getValue(), m);
 344         assertEquals(test.getDayOfMonth(), d);
 345         assertEquals(test.getHour(), h);
 346         assertEquals(test.getMinute(), min);
 347         assertEquals(test.getSecond(), s);
 348         assertEquals(test.getNano(), n);
 349         assertEquals(test.getOffset(), offset);
 350         assertEquals(test.getZone(), zone);
 351     }
 352 
 353     //-----------------------------------------------------------------------
 354     // of(LocalDate, LocalTime, ZoneId)
 355     //-----------------------------------------------------------------------
 356     @Test
 357     public void factory_of_LocalDateLocalTime() {
 358         ZonedDateTime test = ZonedDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 10, 500), ZONE_PARIS);
 359         check(test, 2008, 6, 30, 11, 30, 10, 500, OFFSET_0200, ZONE_PARIS);
 360     }
 361 
 362     @Test
 363     public void factory_of_LocalDateLocalTime_inGap() {
 364         ZonedDateTime test = ZonedDateTime.of(TEST_PARIS_GAP_2008_03_30_02_30.toLocalDate(), TEST_PARIS_GAP_2008_03_30_02_30.toLocalTime(), ZONE_PARIS);
 365         check(test, 2008, 3, 30, 3, 30, 0, 0, OFFSET_0200, ZONE_PARIS);  // one hour later in summer offset
 366     }
 367 
 368     @Test
 369     public void factory_of_LocalDateLocalTime_inOverlap() {
 370         ZonedDateTime test = ZonedDateTime.of(TEST_PARIS_OVERLAP_2008_10_26_02_30.toLocalDate(), TEST_PARIS_OVERLAP_2008_10_26_02_30.toLocalTime(), ZONE_PARIS);
 371         check(test, 2008, 10, 26, 2, 30, 0, 0, OFFSET_0200, ZONE_PARIS);  // same time in summer offset
 372     }
 373 
 374     @Test(expectedExceptions=NullPointerException.class)
 375     public void factory_of_LocalDateLocalTime_nullDate() {
 376         ZonedDateTime.of((LocalDate) null, LocalTime.of(11, 30, 10, 500), ZONE_PARIS);
 377     }
 378 
 379     @Test(expectedExceptions=NullPointerException.class)
 380     public void factory_of_LocalDateLocalTime_nullTime() {
 381         ZonedDateTime.of(LocalDate.of(2008, 6, 30), (LocalTime) null, ZONE_PARIS);
 382     }
 383 
 384     @Test(expectedExceptions=NullPointerException.class)
 385     public void factory_of_LocalDateLocalTime_nullZone() {
 386         ZonedDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 10, 500), null);
 387     }
 388 
 389     //-----------------------------------------------------------------------
 390     // of(LocalDateTime, ZoneId)
 391     //-----------------------------------------------------------------------
 392     @Test
 393     public void factory_of_LocalDateTime() {
 394         LocalDateTime base = LocalDateTime.of(2008, 6, 30, 11, 30, 10, 500);
 395         ZonedDateTime test = ZonedDateTime.of(base, ZONE_PARIS);
 396         check(test, 2008, 6, 30, 11, 30, 10, 500, OFFSET_0200, ZONE_PARIS);
 397     }
 398 
 399     @Test
 400     public void factory_of_LocalDateTime_inGap() {
 401         ZonedDateTime test = ZonedDateTime.of(TEST_PARIS_GAP_2008_03_30_02_30, ZONE_PARIS);
 402         check(test, 2008, 3, 30, 3, 30, 0, 0, OFFSET_0200, ZONE_PARIS);  // one hour later in summer offset
 403     }
 404 
 405     @Test
 406     public void factory_of_LocalDateTime_inOverlap() {
 407         ZonedDateTime test = ZonedDateTime.of(TEST_PARIS_OVERLAP_2008_10_26_02_30, ZONE_PARIS);
 408         check(test, 2008, 10, 26, 2, 30, 0, 0, OFFSET_0200, ZONE_PARIS);  // same time in summer offset
 409     }
 410 
 411     @Test(expectedExceptions=NullPointerException.class)
 412     public void factory_of_LocalDateTime_nullDateTime() {
 413         ZonedDateTime.of((LocalDateTime) null, ZONE_PARIS);
 414     }
 415 
 416     @Test(expectedExceptions=NullPointerException.class)
 417     public void factory_of_LocalDateTime_nullZone() {
 418         LocalDateTime base = LocalDateTime.of(2008, 6, 30, 11, 30, 10, 500);
 419         ZonedDateTime.of(base, null);
 420     }
 421 
 422     //-----------------------------------------------------------------------
 423     // of(int..., ZoneId)
 424     //-----------------------------------------------------------------------
 425     @Test
 426     public void factory_of_ints() {
 427         ZonedDateTime test = ZonedDateTime.of(2008, 6, 30, 11, 30, 10, 500, ZONE_PARIS);
 428         check(test, 2008, 6, 30, 11, 30, 10, 500, OFFSET_0200, ZONE_PARIS);
 429     }
 430 
 431     //-----------------------------------------------------------------------
 432     // ofInstant(Instant, ZoneId)
 433     //-----------------------------------------------------------------------
 434     @Test
 435     public void factory_ofInstant_Instant_ZR() {
 436         Instant instant = LocalDateTime.of(2008, 6, 30, 11, 30, 10, 35).toInstant(OFFSET_0200);
 437         ZonedDateTime test = ZonedDateTime.ofInstant(instant, ZONE_PARIS);
 438         check(test, 2008, 6, 30, 11, 30, 10, 35, OFFSET_0200, ZONE_PARIS);
 439     }
 440 
 441     @Test
 442     public void factory_ofInstant_Instant_ZO() {
 443         Instant instant = LocalDateTime.of(2008, 6, 30, 11, 30, 10, 45).toInstant(OFFSET_0200);
 444         ZonedDateTime test = ZonedDateTime.ofInstant(instant, OFFSET_0200);
 445         check(test, 2008, 6, 30, 11, 30, 10, 45, OFFSET_0200, OFFSET_0200);
 446     }
 447 
 448     @Test
 449     public void factory_ofInstant_Instant_inGap() {
 450         Instant instant = TEST_PARIS_GAP_2008_03_30_02_30.toInstant(OFFSET_0100);
 451         ZonedDateTime test = ZonedDateTime.ofInstant(instant, ZONE_PARIS);
 452         check(test, 2008, 3, 30, 3, 30, 0, 0, OFFSET_0200, ZONE_PARIS);  // one hour later in summer offset
 453     }
 454 
 455     @Test
 456     public void factory_ofInstant_Instant_inOverlap_earlier() {
 457         Instant instant = TEST_PARIS_OVERLAP_2008_10_26_02_30.toInstant(OFFSET_0200);
 458         ZonedDateTime test = ZonedDateTime.ofInstant(instant, ZONE_PARIS);
 459         check(test, 2008, 10, 26, 2, 30, 0, 0, OFFSET_0200, ZONE_PARIS);  // same time and offset
 460     }
 461 
 462     @Test
 463     public void factory_ofInstant_Instant_inOverlap_later() {
 464         Instant instant = TEST_PARIS_OVERLAP_2008_10_26_02_30.toInstant(OFFSET_0100);
 465         ZonedDateTime test = ZonedDateTime.ofInstant(instant, ZONE_PARIS);
 466         check(test, 2008, 10, 26, 2, 30, 0, 0, OFFSET_0100, ZONE_PARIS);  // same time and offset
 467     }
 468 
 469     @Test
 470     public void factory_ofInstant_Instant_invalidOffset() {
 471         Instant instant = LocalDateTime.of(2008, 6, 30, 11, 30, 10, 500).toInstant(OFFSET_0130);
 472         ZonedDateTime test = ZonedDateTime.ofInstant(instant, ZONE_PARIS);
 473         check(test, 2008, 6, 30, 12, 0, 10, 500, OFFSET_0200, ZONE_PARIS);  // corrected offset, thus altered time
 474     }
 475 
 476     @Test
 477     public void factory_ofInstant_allSecsInDay() {
 478         for (int i = 0; i < (24 * 60 * 60); i++) {
 479             Instant instant = Instant.ofEpochSecond(i);
 480             ZonedDateTime test = ZonedDateTime.ofInstant(instant, OFFSET_0100);
 481             assertEquals(test.getYear(), 1970);
 482             assertEquals(test.getMonth(), Month.JANUARY);
 483             assertEquals(test.getDayOfMonth(), 1 + (i >= 23 * 60 * 60 ? 1 : 0));
 484             assertEquals(test.getHour(), ((i / (60 * 60)) + 1) % 24);
 485             assertEquals(test.getMinute(), (i / 60) % 60);
 486             assertEquals(test.getSecond(), i % 60);
 487         }
 488     }
 489 
 490     @Test
 491     public void factory_ofInstant_allDaysInCycle() {
 492         // sanity check using different algorithm
 493         ZonedDateTime expected = LocalDateTime.of(1970, 1, 1, 0, 0, 0, 0).atZone(ZoneOffset.UTC);
 494         for (long i = 0; i < 146097; i++) {
 495             Instant instant = Instant.ofEpochSecond(i * 24L * 60L * 60L);
 496             ZonedDateTime test = ZonedDateTime.ofInstant(instant, ZoneOffset.UTC);
 497             assertEquals(test, expected);
 498             expected = expected.plusDays(1);
 499         }
 500     }
 501 
 502     @Test
 503     public void factory_ofInstant_minWithMinOffset() {
 504         long days_0000_to_1970 = (146097 * 5) - (30 * 365 + 7);
 505         int year = Year.MIN_VALUE;
 506         long days = (year * 365L + (year / 4 - year / 100 + year / 400)) - days_0000_to_1970;
 507         Instant instant = Instant.ofEpochSecond(days * 24L * 60L * 60L - OFFSET_MIN.getTotalSeconds());
 508         ZonedDateTime test = ZonedDateTime.ofInstant(instant, OFFSET_MIN);
 509         assertEquals(test.getYear(), Year.MIN_VALUE);
 510         assertEquals(test.getMonth().getValue(), 1);
 511         assertEquals(test.getDayOfMonth(), 1);
 512         assertEquals(test.getOffset(), OFFSET_MIN);
 513         assertEquals(test.getHour(), 0);
 514         assertEquals(test.getMinute(), 0);
 515         assertEquals(test.getSecond(), 0);
 516         assertEquals(test.getNano(), 0);
 517     }
 518 
 519     @Test
 520     public void factory_ofInstant_minWithMaxOffset() {
 521         long days_0000_to_1970 = (146097 * 5) - (30 * 365 + 7);
 522         int year = Year.MIN_VALUE;
 523         long days = (year * 365L + (year / 4 - year / 100 + year / 400)) - days_0000_to_1970;
 524         Instant instant = Instant.ofEpochSecond(days * 24L * 60L * 60L - OFFSET_MAX.getTotalSeconds());
 525         ZonedDateTime test = ZonedDateTime.ofInstant(instant, OFFSET_MAX);
 526         assertEquals(test.getYear(), Year.MIN_VALUE);
 527         assertEquals(test.getMonth().getValue(), 1);
 528         assertEquals(test.getDayOfMonth(), 1);
 529         assertEquals(test.getOffset(), OFFSET_MAX);
 530         assertEquals(test.getHour(), 0);
 531         assertEquals(test.getMinute(), 0);
 532         assertEquals(test.getSecond(), 0);
 533         assertEquals(test.getNano(), 0);
 534     }
 535 
 536     @Test
 537     public void factory_ofInstant_maxWithMinOffset() {
 538         long days_0000_to_1970 = (146097 * 5) - (30 * 365 + 7);
 539         int year = Year.MAX_VALUE;
 540         long days = (year * 365L + (year / 4 - year / 100 + year / 400)) + 365 - days_0000_to_1970;
 541         Instant instant = Instant.ofEpochSecond((days + 1) * 24L * 60L * 60L - 1 - OFFSET_MIN.getTotalSeconds());
 542         ZonedDateTime test = ZonedDateTime.ofInstant(instant, OFFSET_MIN);
 543         assertEquals(test.getYear(), Year.MAX_VALUE);
 544         assertEquals(test.getMonth().getValue(), 12);
 545         assertEquals(test.getDayOfMonth(), 31);
 546         assertEquals(test.getOffset(), OFFSET_MIN);
 547         assertEquals(test.getHour(), 23);
 548         assertEquals(test.getMinute(), 59);
 549         assertEquals(test.getSecond(), 59);
 550         assertEquals(test.getNano(), 0);
 551     }
 552 
 553     @Test
 554     public void factory_ofInstant_maxWithMaxOffset() {
 555         long days_0000_to_1970 = (146097 * 5) - (30 * 365 + 7);
 556         int year = Year.MAX_VALUE;
 557         long days = (year * 365L + (year / 4 - year / 100 + year / 400)) + 365 - days_0000_to_1970;
 558         Instant instant = Instant.ofEpochSecond((days + 1) * 24L * 60L * 60L - 1 - OFFSET_MAX.getTotalSeconds());
 559         ZonedDateTime test = ZonedDateTime.ofInstant(instant, OFFSET_MAX);
 560         assertEquals(test.getYear(), Year.MAX_VALUE);
 561         assertEquals(test.getMonth().getValue(), 12);
 562         assertEquals(test.getDayOfMonth(), 31);
 563         assertEquals(test.getOffset(), OFFSET_MAX);
 564         assertEquals(test.getHour(), 23);
 565         assertEquals(test.getMinute(), 59);
 566         assertEquals(test.getSecond(), 59);
 567         assertEquals(test.getNano(), 0);
 568     }
 569 
 570     //-----------------------------------------------------------------------
 571     @Test(expectedExceptions=DateTimeException.class)
 572     public void factory_ofInstant_maxInstantWithMaxOffset() {
 573         Instant instant = Instant.ofEpochSecond(Long.MAX_VALUE);
 574         ZonedDateTime.ofInstant(instant, OFFSET_MAX);
 575     }
 576 
 577     @Test(expectedExceptions=DateTimeException.class)
 578     public void factory_ofInstant_maxInstantWithMinOffset() {
 579         Instant instant = Instant.ofEpochSecond(Long.MAX_VALUE);
 580         ZonedDateTime.ofInstant(instant, OFFSET_MIN);
 581     }
 582 
 583     @Test(expectedExceptions=DateTimeException.class)
 584     public void factory_ofInstant_tooBig() {
 585         long days_0000_to_1970 = (146097 * 5) - (30 * 365 + 7);
 586         long year = Year.MAX_VALUE + 1L;
 587         long days = (year * 365L + (year / 4 - year / 100 + year / 400)) - days_0000_to_1970;
 588         Instant instant = Instant.ofEpochSecond(days * 24L * 60L * 60L);
 589         ZonedDateTime.ofInstant(instant, ZoneOffset.UTC);
 590     }
 591 
 592     @Test(expectedExceptions=DateTimeException.class)
 593     public void factory_ofInstant_tooLow() {
 594         long days_0000_to_1970 = (146097 * 5) - (30 * 365 + 7);
 595         int year = Year.MIN_VALUE - 1;
 596         long days = (year * 365L + (year / 4 - year / 100 + year / 400)) - days_0000_to_1970;
 597         Instant instant = Instant.ofEpochSecond(days * 24L * 60L * 60L);
 598         ZonedDateTime.ofInstant(instant, ZoneOffset.UTC);
 599     }
 600 
 601     @Test(expectedExceptions=NullPointerException.class)
 602     public void factory_ofInstant_Instant_nullInstant() {
 603         ZonedDateTime.ofInstant((Instant) null, ZONE_0100);
 604     }
 605 
 606     @Test(expectedExceptions=NullPointerException.class)
 607     public void factory_ofInstant_Instant_nullZone() {
 608         ZonedDateTime.ofInstant(Instant.EPOCH, null);
 609     }
 610 
 611     //-----------------------------------------------------------------------
 612     // ofStrict(LocalDateTime, ZoneId, ZoneOffset)
 613     //-----------------------------------------------------------------------
 614     @Test
 615     public void factory_ofStrict_LDT_ZI_ZO() {
 616         LocalDateTime normal = LocalDateTime.of(2008, 6, 30, 11, 30, 10, 500);
 617         ZonedDateTime test = ZonedDateTime.ofStrict(normal, OFFSET_0200, ZONE_PARIS);
 618         check(test, 2008, 6, 30, 11, 30, 10, 500, OFFSET_0200, ZONE_PARIS);
 619     }
 620 
 621     @Test(expectedExceptions=DateTimeException.class)
 622     public void factory_ofStrict_LDT_ZI_ZO_inGap() {
 623         try {
 624             ZonedDateTime.ofStrict(TEST_PARIS_GAP_2008_03_30_02_30, OFFSET_0100, ZONE_PARIS);
 625         } catch (DateTimeException ex) {
 626             assertEquals(ex.getMessage().contains(" gap"), true);
 627             throw ex;
 628         }
 629     }
 630 
 631     @Test(expectedExceptions=DateTimeException.class)
 632     public void factory_ofStrict_LDT_ZI_ZO_inOverlap_invalidOfset() {
 633         try {
 634             ZonedDateTime.ofStrict(TEST_PARIS_OVERLAP_2008_10_26_02_30, OFFSET_0130, ZONE_PARIS);
 635         } catch (DateTimeException ex) {
 636             assertEquals(ex.getMessage().contains(" is not valid for "), true);
 637             throw ex;
 638         }
 639     }
 640 
 641     @Test(expectedExceptions=DateTimeException.class)
 642     public void factory_ofStrict_LDT_ZI_ZO_invalidOffset() {
 643         try {
 644             ZonedDateTime.ofStrict(TEST_LOCAL_2008_06_30_11_30_59_500, OFFSET_0130, ZONE_PARIS);
 645         } catch (DateTimeException ex) {
 646             assertEquals(ex.getMessage().contains(" is not valid for "), true);
 647             throw ex;
 648         }
 649     }
 650 
 651     @Test(expectedExceptions=NullPointerException.class)
 652     public void factory_ofStrict_LDT_ZI_ZO_nullLDT() {
 653         ZonedDateTime.ofStrict((LocalDateTime) null, OFFSET_0100, ZONE_PARIS);
 654     }
 655 
 656     @Test(expectedExceptions=NullPointerException.class)
 657     public void factory_ofStrict_LDT_ZI_ZO_nullZO() {
 658         ZonedDateTime.ofStrict(TEST_LOCAL_2008_06_30_11_30_59_500, null, ZONE_PARIS);
 659     }
 660 
 661     @Test(expectedExceptions=NullPointerException.class)
 662     public void factory_ofStrict_LDT_ZI_ZO_nullZI() {
 663         ZonedDateTime.ofStrict(TEST_LOCAL_2008_06_30_11_30_59_500, OFFSET_0100, null);
 664     }
 665 
 666     //-----------------------------------------------------------------------
 667     // from(TemporalAccessor)
 668     //-----------------------------------------------------------------------
 669     @Test
 670     public void factory_from_TemporalAccessor_ZDT() {
 671         assertEquals(ZonedDateTime.from(TEST_DATE_TIME_PARIS), TEST_DATE_TIME_PARIS);
 672     }
 673 
 674     @Test
 675     public void factory_from_TemporalAccessor_LDT_ZoneId() {
 676         assertEquals(ZonedDateTime.from(new TemporalAccessor() {
 677             @Override
 678             public boolean isSupported(TemporalField field) {
 679                 return TEST_DATE_TIME_PARIS.toLocalDateTime().isSupported(field);
 680             }
 681 
 682             @Override
 683             public long getLong(TemporalField field) {
 684                 return TEST_DATE_TIME_PARIS.toLocalDateTime().getLong(field);
 685             }
 686 
 687             @SuppressWarnings("unchecked")
 688             @Override
 689             public <R> R query(TemporalQuery<R> query) {
 690                 if (query == TemporalQueries.zoneId()) {
 691                     return (R) TEST_DATE_TIME_PARIS.getZone();
 692                 }
 693                 return TemporalAccessor.super.query(query);
 694             }
 695         }), TEST_DATE_TIME_PARIS);
 696     }
 697 
 698     @Test
 699     public void factory_from_TemporalAccessor_Instant_ZoneId() {
 700         assertEquals(ZonedDateTime.from(new TemporalAccessor() {
 701             @Override
 702             public boolean isSupported(TemporalField field) {
 703                 return field == INSTANT_SECONDS || field == NANO_OF_SECOND;
 704             }
 705 
 706             @Override
 707             public long getLong(TemporalField field) {
 708                 return TEST_DATE_TIME_PARIS.toInstant().getLong(field);
 709             }
 710 
 711             @SuppressWarnings("unchecked")
 712             @Override
 713             public <R> R query(TemporalQuery<R> query) {
 714                 if (query == TemporalQueries.zoneId()) {
 715                     return (R) TEST_DATE_TIME_PARIS.getZone();
 716                 }
 717                 return TemporalAccessor.super.query(query);
 718             }
 719         }), TEST_DATE_TIME_PARIS);
 720     }
 721 
 722     @Test(expectedExceptions=DateTimeException.class)
 723     public void factory_from_TemporalAccessor_invalid_noDerive() {
 724         ZonedDateTime.from(LocalTime.of(12, 30));
 725     }
 726 
 727     @Test(expectedExceptions=NullPointerException.class)
 728     public void factory_from_TemporalAccessor_null() {
 729         ZonedDateTime.from((TemporalAccessor) null);
 730     }
 731 
 732     //-----------------------------------------------------------------------
 733     // parse()
 734     //-----------------------------------------------------------------------
 735     @Test(dataProvider="sampleToString")
 736     public void test_parse(int y, int month, int d, int h, int m, int s, int n, String zoneId, String text) {
 737         ZonedDateTime t = ZonedDateTime.parse(text);
 738         assertEquals(t.getYear(), y);
 739         assertEquals(t.getMonth().getValue(), month);
 740         assertEquals(t.getDayOfMonth(), d);
 741         assertEquals(t.getHour(), h);
 742         assertEquals(t.getMinute(), m);
 743         assertEquals(t.getSecond(), s);
 744         assertEquals(t.getNano(), n);
 745         assertEquals(t.getZone().getId(), zoneId);
 746     }
 747 
 748     @DataProvider(name="parseAdditional")
 749     Object[][] data_parseAdditional() {
 750         return new Object[][] {
 751                 {"2012-06-30T12:30:40Z[GMT]", 2012, 6, 30, 12, 30, 40, 0, "GMT"},
 752                 {"2012-06-30T12:30:40Z[UT]", 2012, 6, 30, 12, 30, 40, 0, "UT"},
 753                 {"2012-06-30T12:30:40Z[UTC]", 2012, 6, 30, 12, 30, 40, 0, "UTC"},
 754                 {"2012-06-30T12:30:40+01:00[Z]", 2012, 6, 30, 11, 30, 40, 0, "Z"},
 755                 {"2012-06-30T12:30:40+01:00[+01:00]", 2012, 6, 30, 12, 30, 40, 0, "+01:00"},
 756                 {"2012-06-30T12:30:40+01:00[GMT+01:00]", 2012, 6, 30, 12, 30, 40, 0, "GMT+01:00"},
 757                 {"2012-06-30T12:30:40+01:00[UT+01:00]", 2012, 6, 30, 12, 30, 40, 0, "UT+01:00"},
 758                 {"2012-06-30T12:30:40+01:00[UTC+01:00]", 2012, 6, 30, 12, 30, 40, 0, "UTC+01:00"},
 759                 {"2012-06-30T12:30:40-01:00[-01:00]", 2012, 6, 30, 12, 30, 40, 0, "-01:00"},
 760                 {"2012-06-30T12:30:40-01:00[GMT-01:00]", 2012, 6, 30, 12, 30, 40, 0, "GMT-01:00"},
 761                 {"2012-06-30T12:30:40-01:00[UT-01:00]", 2012, 6, 30, 12, 30, 40, 0, "UT-01:00"},
 762                 {"2012-06-30T12:30:40-01:00[UTC-01:00]", 2012, 6, 30, 12, 30, 40, 0, "UTC-01:00"},
 763                 {"2012-06-30T12:30:40+01:00[Europe/London]", 2012, 6, 30, 12, 30, 40, 0, "Europe/London"},
 764                 {"2012-06-30T12:30:40+01", 2012, 6, 30, 12, 30, 40, 0, "+01:00"},
 765         };
 766     }
 767 
 768     @Test(dataProvider="parseAdditional")
 769     public void test_parseAdditional(String text, int y, int month, int d, int h, int m, int s, int n, String zoneId) {
 770         ZonedDateTime t = ZonedDateTime.parse(text);
 771         assertEquals(t.getYear(), y);
 772         assertEquals(t.getMonth().getValue(), month);
 773         assertEquals(t.getDayOfMonth(), d);
 774         assertEquals(t.getHour(), h);
 775         assertEquals(t.getMinute(), m);
 776         assertEquals(t.getSecond(), s);
 777         assertEquals(t.getNano(), n);
 778         assertEquals(t.getZone().getId(), zoneId);
 779     }
 780 
 781     @Test(expectedExceptions=DateTimeParseException.class)
 782     public void factory_parse_illegalValue() {
 783         ZonedDateTime.parse("2008-06-32T11:15+01:00[Europe/Paris]");
 784     }
 785 
 786     @Test(expectedExceptions=DateTimeParseException.class)
 787     public void factory_parse_invalidValue() {
 788         ZonedDateTime.parse("2008-06-31T11:15+01:00[Europe/Paris]");
 789     }
 790 
 791     @Test(expectedExceptions=NullPointerException.class)
 792     public void factory_parse_nullText() {
 793         ZonedDateTime.parse((String) null);
 794     }
 795 
 796     //-----------------------------------------------------------------------
 797     // parse(DateTimeFormatter)
 798     //-----------------------------------------------------------------------
 799     @Test
 800     public void factory_parse_formatter() {
 801         DateTimeFormatter f = DateTimeFormatter.ofPattern("y M d H m s VV");
 802         ZonedDateTime test = ZonedDateTime.parse("2010 12 3 11 30 0 Europe/London", f);
 803         assertEquals(test, ZonedDateTime.of(LocalDateTime.of(2010, 12, 3, 11, 30), ZoneId.of("Europe/London")));
 804     }
 805 
 806     @Test(expectedExceptions=NullPointerException.class)
 807     public void factory_parse_formatter_nullText() {
 808         DateTimeFormatter f = DateTimeFormatter.ofPattern("y M d H m s");
 809         ZonedDateTime.parse((String) null, f);
 810     }
 811 
 812     @Test(expectedExceptions=NullPointerException.class)
 813     public void factory_parse_formatter_nullFormatter() {
 814         ZonedDateTime.parse("ANY", null);
 815     }
 816 
 817     //-----------------------------------------------------------------------
 818     // basics
 819     //-----------------------------------------------------------------------
 820     @DataProvider(name="sampleTimes")
 821     Object[][] provider_sampleTimes() {
 822         return new Object[][] {
 823             {2008, 6, 30, 11, 30, 20, 500, ZONE_0100},
 824             {2008, 6, 30, 11, 0, 0, 0, ZONE_0100},
 825             {2008, 6, 30, 11, 30, 20, 500, ZONE_PARIS},
 826             {2008, 6, 30, 11, 0, 0, 0, ZONE_PARIS},
 827             {2008, 6, 30, 23, 59, 59, 999999999, ZONE_0100},
 828             {-1, 1, 1, 0, 0, 0, 0, ZONE_0100},
 829         };
 830     }
 831 
 832     @Test(dataProvider="sampleTimes")
 833     public void test_get(int y, int o, int d, int h, int m, int s, int n, ZoneId zone) {
 834         LocalDate localDate = LocalDate.of(y, o, d);
 835         LocalTime localTime = LocalTime.of(h, m, s, n);
 836         LocalDateTime localDateTime = LocalDateTime.of(localDate, localTime);
 837         ZoneOffset offset = zone.getRules().getOffset(localDateTime);
 838         ZonedDateTime a = ZonedDateTime.of(localDateTime, zone);
 839 
 840         assertEquals(a.getYear(), localDate.getYear());
 841         assertEquals(a.getMonth(), localDate.getMonth());
 842         assertEquals(a.getDayOfMonth(), localDate.getDayOfMonth());
 843         assertEquals(a.getDayOfYear(), localDate.getDayOfYear());
 844         assertEquals(a.getDayOfWeek(), localDate.getDayOfWeek());
 845 
 846         assertEquals(a.getHour(), localTime.getHour());
 847         assertEquals(a.getMinute(), localTime.getMinute());
 848         assertEquals(a.getSecond(), localTime.getSecond());
 849         assertEquals(a.getNano(), localTime.getNano());
 850 
 851         assertEquals(a.toLocalDate(), localDate);
 852         assertEquals(a.toLocalTime(), localTime);
 853         assertEquals(a.toLocalDateTime(), localDateTime);
 854         if (zone instanceof ZoneOffset) {
 855             assertEquals(a.toString(), localDateTime.toString() + offset.toString());
 856         } else {
 857             assertEquals(a.toString(), localDateTime.toString() + offset.toString() + "[" + zone.toString() + "]");
 858         }
 859     }
 860 
 861     //-----------------------------------------------------------------------
 862     // isSupported(TemporalField)
 863     //-----------------------------------------------------------------------
 864     @Test
 865     public void test_isSupported_TemporalField() {
 866         assertEquals(TEST_DATE_TIME.isSupported((TemporalField) null), false);
 867         assertEquals(TEST_DATE_TIME.isSupported(ChronoField.NANO_OF_SECOND), true);
 868         assertEquals(TEST_DATE_TIME.isSupported(ChronoField.NANO_OF_DAY), true);
 869         assertEquals(TEST_DATE_TIME.isSupported(ChronoField.MICRO_OF_SECOND), true);
 870         assertEquals(TEST_DATE_TIME.isSupported(ChronoField.MICRO_OF_DAY), true);
 871         assertEquals(TEST_DATE_TIME.isSupported(ChronoField.MILLI_OF_SECOND), true);
 872         assertEquals(TEST_DATE_TIME.isSupported(ChronoField.MILLI_OF_DAY), true);
 873         assertEquals(TEST_DATE_TIME.isSupported(ChronoField.SECOND_OF_MINUTE), true);
 874         assertEquals(TEST_DATE_TIME.isSupported(ChronoField.SECOND_OF_DAY), true);
 875         assertEquals(TEST_DATE_TIME.isSupported(ChronoField.MINUTE_OF_HOUR), true);
 876         assertEquals(TEST_DATE_TIME.isSupported(ChronoField.MINUTE_OF_DAY), true);
 877         assertEquals(TEST_DATE_TIME.isSupported(ChronoField.HOUR_OF_AMPM), true);
 878         assertEquals(TEST_DATE_TIME.isSupported(ChronoField.CLOCK_HOUR_OF_AMPM), true);
 879         assertEquals(TEST_DATE_TIME.isSupported(ChronoField.HOUR_OF_DAY), true);
 880         assertEquals(TEST_DATE_TIME.isSupported(ChronoField.CLOCK_HOUR_OF_DAY), true);
 881         assertEquals(TEST_DATE_TIME.isSupported(ChronoField.AMPM_OF_DAY), true);
 882         assertEquals(TEST_DATE_TIME.isSupported(ChronoField.DAY_OF_WEEK), true);
 883         assertEquals(TEST_DATE_TIME.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), true);
 884         assertEquals(TEST_DATE_TIME.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR), true);
 885         assertEquals(TEST_DATE_TIME.isSupported(ChronoField.DAY_OF_MONTH), true);
 886         assertEquals(TEST_DATE_TIME.isSupported(ChronoField.DAY_OF_YEAR), true);
 887         assertEquals(TEST_DATE_TIME.isSupported(ChronoField.EPOCH_DAY), true);
 888         assertEquals(TEST_DATE_TIME.isSupported(ChronoField.ALIGNED_WEEK_OF_MONTH), true);
 889         assertEquals(TEST_DATE_TIME.isSupported(ChronoField.ALIGNED_WEEK_OF_YEAR), true);
 890         assertEquals(TEST_DATE_TIME.isSupported(ChronoField.MONTH_OF_YEAR), true);
 891         assertEquals(TEST_DATE_TIME.isSupported(ChronoField.PROLEPTIC_MONTH), true);
 892         assertEquals(TEST_DATE_TIME.isSupported(ChronoField.YEAR), true);
 893         assertEquals(TEST_DATE_TIME.isSupported(ChronoField.YEAR_OF_ERA), true);
 894         assertEquals(TEST_DATE_TIME.isSupported(ChronoField.ERA), true);
 895         assertEquals(TEST_DATE_TIME.isSupported(ChronoField.INSTANT_SECONDS), true);
 896         assertEquals(TEST_DATE_TIME.isSupported(ChronoField.OFFSET_SECONDS), true);
 897     }
 898 
 899     //-----------------------------------------------------------------------
 900     // isSupported(TemporalUnit)
 901     //-----------------------------------------------------------------------
 902     @Test
 903     public void test_isSupported_TemporalUnit() {
 904         assertEquals(TEST_DATE_TIME.isSupported((TemporalUnit) null), false);
 905         assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.NANOS), true);
 906         assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.MICROS), true);
 907         assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.MILLIS), true);
 908         assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.SECONDS), true);
 909         assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.MINUTES), true);
 910         assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.HOURS), true);
 911         assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.HALF_DAYS), true);
 912         assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.DAYS), true);
 913         assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.WEEKS), true);
 914         assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.MONTHS), true);
 915         assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.YEARS), true);
 916         assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.DECADES), true);
 917         assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.CENTURIES), true);
 918         assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.MILLENNIA), true);
 919         assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.ERAS), true);
 920         assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.FOREVER), false);
 921     }
 922 
 923     //-----------------------------------------------------------------------
 924     // get(TemporalField)
 925     //-----------------------------------------------------------------------
 926     @Test
 927     public void test_get_TemporalField() {
 928         ZonedDateTime test = ZonedDateTime.of(LocalDateTime.of(2008, 6, 30, 12, 30, 40, 987654321), ZONE_0100);
 929         assertEquals(test.get(ChronoField.YEAR), 2008);
 930         assertEquals(test.get(ChronoField.MONTH_OF_YEAR), 6);
 931         assertEquals(test.get(ChronoField.DAY_OF_MONTH), 30);
 932         assertEquals(test.get(ChronoField.DAY_OF_WEEK), 1);
 933         assertEquals(test.get(ChronoField.DAY_OF_YEAR), 182);
 934 
 935         assertEquals(test.get(ChronoField.HOUR_OF_DAY), 12);
 936         assertEquals(test.get(ChronoField.MINUTE_OF_HOUR), 30);
 937         assertEquals(test.get(ChronoField.SECOND_OF_MINUTE), 40);
 938         assertEquals(test.get(ChronoField.NANO_OF_SECOND), 987654321);
 939         assertEquals(test.get(ChronoField.HOUR_OF_AMPM), 0);
 940         assertEquals(test.get(ChronoField.AMPM_OF_DAY), 1);
 941 
 942         assertEquals(test.get(ChronoField.OFFSET_SECONDS), 3600);
 943     }
 944 
 945     @Test
 946     public void test_getLong_TemporalField() {
 947         ZonedDateTime test = ZonedDateTime.of(LocalDateTime.of(2008, 6, 30, 12, 30, 40, 987654321), ZONE_0100);
 948         assertEquals(test.getLong(ChronoField.YEAR), 2008);
 949         assertEquals(test.getLong(ChronoField.MONTH_OF_YEAR), 6);
 950         assertEquals(test.getLong(ChronoField.DAY_OF_MONTH), 30);
 951         assertEquals(test.getLong(ChronoField.DAY_OF_WEEK), 1);
 952         assertEquals(test.getLong(ChronoField.DAY_OF_YEAR), 182);
 953 
 954         assertEquals(test.getLong(ChronoField.HOUR_OF_DAY), 12);
 955         assertEquals(test.getLong(ChronoField.MINUTE_OF_HOUR), 30);
 956         assertEquals(test.getLong(ChronoField.SECOND_OF_MINUTE), 40);
 957         assertEquals(test.getLong(ChronoField.NANO_OF_SECOND), 987654321);
 958         assertEquals(test.getLong(ChronoField.HOUR_OF_AMPM), 0);
 959         assertEquals(test.getLong(ChronoField.AMPM_OF_DAY), 1);
 960 
 961         assertEquals(test.getLong(ChronoField.OFFSET_SECONDS), 3600);
 962         assertEquals(test.getLong(ChronoField.INSTANT_SECONDS), test.toEpochSecond());
 963     }
 964 
 965     //-----------------------------------------------------------------------
 966     // query(TemporalQuery)
 967     //-----------------------------------------------------------------------
 968     @Test
 969     public void test_query_chrono() {
 970         assertEquals(TEST_DATE_TIME.query(TemporalQueries.chronology()), IsoChronology.INSTANCE);
 971         assertEquals(TemporalQueries.chronology().queryFrom(TEST_DATE_TIME), IsoChronology.INSTANCE);
 972     }
 973 
 974     @Test
 975     public void test_query_zoneId() {
 976         assertEquals(TEST_DATE_TIME.query(TemporalQueries.zoneId()), TEST_DATE_TIME.getZone());
 977         assertEquals(TemporalQueries.zoneId().queryFrom(TEST_DATE_TIME), TEST_DATE_TIME.getZone());
 978     }
 979 
 980     @Test
 981     public void test_query_precision() {
 982         assertEquals(TEST_DATE_TIME.query(TemporalQueries.precision()), NANOS);
 983         assertEquals(TemporalQueries.precision().queryFrom(TEST_DATE_TIME), NANOS);
 984     }
 985 
 986     @Test
 987     public void test_query_offset() {
 988         assertEquals(TEST_DATE_TIME.query(TemporalQueries.offset()), TEST_DATE_TIME.getOffset());
 989         assertEquals(TemporalQueries.offset().queryFrom(TEST_DATE_TIME), TEST_DATE_TIME.getOffset());
 990     }
 991 
 992     @Test
 993     public void test_query_zone() {
 994         assertEquals(TEST_DATE_TIME.query(TemporalQueries.zone()), TEST_DATE_TIME.getZone());
 995         assertEquals(TemporalQueries.zone().queryFrom(TEST_DATE_TIME), TEST_DATE_TIME.getZone());
 996     }
 997 
 998     @Test(expectedExceptions=NullPointerException.class)
 999     public void test_query_null() {
1000         TEST_DATE_TIME.query(null);
1001     }
1002 
1003     //-----------------------------------------------------------------------
1004     // withEarlierOffsetAtOverlap()
1005     //-----------------------------------------------------------------------
1006     @Test
1007     public void test_withEarlierOffsetAtOverlap_notAtOverlap() {
1008         ZonedDateTime base = ZonedDateTime.ofStrict(TEST_LOCAL_2008_06_30_11_30_59_500, OFFSET_0200, ZONE_PARIS);
1009         ZonedDateTime test = base.withEarlierOffsetAtOverlap();
1010         assertEquals(test, base);  // not changed
1011     }
1012 
1013     @Test
1014     public void test_withEarlierOffsetAtOverlap_atOverlap() {
1015         ZonedDateTime base = ZonedDateTime.ofStrict(TEST_PARIS_OVERLAP_2008_10_26_02_30, OFFSET_0100, ZONE_PARIS);
1016         ZonedDateTime test = base.withEarlierOffsetAtOverlap();
1017         assertEquals(test.getOffset(), OFFSET_0200);  // offset changed to earlier
1018         assertEquals(test.toLocalDateTime(), base.toLocalDateTime());  // date-time not changed
1019     }
1020 
1021     @Test
1022     public void test_withEarlierOffsetAtOverlap_atOverlap_noChange() {
1023         ZonedDateTime base = ZonedDateTime.ofStrict(TEST_PARIS_OVERLAP_2008_10_26_02_30, OFFSET_0200, ZONE_PARIS);
1024         ZonedDateTime test = base.withEarlierOffsetAtOverlap();
1025         assertEquals(test, base);  // not changed
1026     }
1027 
1028     //-----------------------------------------------------------------------
1029     // withLaterOffsetAtOverlap()
1030     //-----------------------------------------------------------------------
1031     @Test
1032     public void test_withLaterOffsetAtOverlap_notAtOverlap() {
1033         ZonedDateTime base = ZonedDateTime.ofStrict(TEST_LOCAL_2008_06_30_11_30_59_500, OFFSET_0200, ZONE_PARIS);
1034         ZonedDateTime test = base.withLaterOffsetAtOverlap();
1035         assertEquals(test, base);  // not changed
1036     }
1037 
1038     @Test
1039     public void test_withLaterOffsetAtOverlap_atOverlap() {
1040         ZonedDateTime base = ZonedDateTime.ofStrict(TEST_PARIS_OVERLAP_2008_10_26_02_30, OFFSET_0200, ZONE_PARIS);
1041         ZonedDateTime test = base.withLaterOffsetAtOverlap();
1042         assertEquals(test.getOffset(), OFFSET_0100);  // offset changed to later
1043         assertEquals(test.toLocalDateTime(), base.toLocalDateTime());  // date-time not changed
1044     }
1045 
1046     @Test
1047     public void test_withLaterOffsetAtOverlap_atOverlap_noChange() {
1048         ZonedDateTime base = ZonedDateTime.ofStrict(TEST_PARIS_OVERLAP_2008_10_26_02_30, OFFSET_0100, ZONE_PARIS);
1049         ZonedDateTime test = base.withLaterOffsetAtOverlap();
1050         assertEquals(test, base);  // not changed
1051     }
1052 
1053     //-----------------------------------------------------------------------
1054     // withZoneSameLocal(ZoneId)
1055     //-----------------------------------------------------------------------
1056     @Test
1057     public void test_withZoneSameLocal() {
1058         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1059         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1060         ZonedDateTime test = base.withZoneSameLocal(ZONE_0200);
1061         assertEquals(test.toLocalDateTime(), base.toLocalDateTime());
1062     }
1063 
1064     @Test
1065     public void test_withZoneSameLocal_noChange() {
1066         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1067         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1068         ZonedDateTime test = base.withZoneSameLocal(ZONE_0100);
1069         assertEquals(test, base);
1070     }
1071 
1072     @Test
1073     public void test_withZoneSameLocal_retainOffset1() {
1074         LocalDateTime ldt = LocalDateTime.of(2008, 11, 2, 1, 30, 59, 0);  // overlap
1075         ZonedDateTime base = ZonedDateTime.of(ldt, ZoneId.of("UTC-04:00") );
1076         ZonedDateTime test = base.withZoneSameLocal(ZoneId.of("America/New_York"));
1077         assertEquals(base.getOffset(), ZoneOffset.ofHours(-4));
1078         assertEquals(test.getOffset(), ZoneOffset.ofHours(-4));
1079     }
1080 
1081     @Test
1082     public void test_withZoneSameLocal_retainOffset2() {
1083         LocalDateTime ldt = LocalDateTime.of(2008, 11, 2, 1, 30, 59, 0);  // overlap
1084         ZonedDateTime base = ZonedDateTime.of(ldt, ZoneId.of("UTC-05:00") );
1085         ZonedDateTime test = base.withZoneSameLocal(ZoneId.of("America/New_York"));
1086         assertEquals(base.getOffset(), ZoneOffset.ofHours(-5));
1087         assertEquals(test.getOffset(), ZoneOffset.ofHours(-5));
1088     }
1089 
1090     @Test(expectedExceptions=NullPointerException.class)
1091     public void test_withZoneSameLocal_null() {
1092         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1093         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1094         base.withZoneSameLocal(null);
1095     }
1096 
1097     //-----------------------------------------------------------------------
1098     // withZoneSameInstant()
1099     //-----------------------------------------------------------------------
1100     @Test
1101     public void test_withZoneSameInstant() {
1102         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1103         ZonedDateTime test = base.withZoneSameInstant(ZONE_0200);
1104         ZonedDateTime expected = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500.plusHours(1), ZONE_0200);
1105         assertEquals(test, expected);
1106     }
1107 
1108     @Test
1109     public void test_withZoneSameInstant_noChange() {
1110         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1111         ZonedDateTime test = base.withZoneSameInstant(ZONE_0100);
1112         assertEquals(test, base);
1113     }
1114 
1115     @Test(expectedExceptions=NullPointerException.class)
1116     public void test_withZoneSameInstant_null() {
1117         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1118         base.withZoneSameInstant(null);
1119     }
1120 
1121     //-----------------------------------------------------------------------
1122     // withFixedOffsetZone()
1123     //-----------------------------------------------------------------------
1124     @Test
1125     public void test_withZoneLocked() {
1126         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_PARIS);
1127         ZonedDateTime test = base.withFixedOffsetZone();
1128         ZonedDateTime expected = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0200);
1129         assertEquals(test, expected);
1130     }
1131 
1132     //-----------------------------------------------------------------------
1133     // with(TemporalAdjuster)
1134     //-----------------------------------------------------------------------
1135     @Test
1136     public void test_with_adjuster_LocalDateTime_sameOffset() {
1137         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_PARIS);
1138         ZonedDateTime test = base.with(LocalDateTime.of(2012, 7, 15, 14, 30));
1139         check(test, 2012, 7, 15, 14, 30, 0, 0, OFFSET_0200, ZONE_PARIS);
1140     }
1141 
1142     @Test
1143     public void test_with_adjuster_LocalDateTime_adjustedOffset() {
1144         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_PARIS);
1145         ZonedDateTime test = base.with(LocalDateTime.of(2012, 1, 15, 14, 30));
1146         check(test, 2012, 1, 15, 14, 30, 0, 0, OFFSET_0100, ZONE_PARIS);
1147     }
1148 
1149     @Test
1150     public void test_with_adjuster_LocalDate() {
1151         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_PARIS);
1152         ZonedDateTime test = base.with(LocalDate.of(2012, 7, 28));
1153         check(test, 2012, 7, 28, 11, 30, 59, 500, OFFSET_0200, ZONE_PARIS);
1154     }
1155 
1156     @Test
1157     public void test_with_adjuster_LocalTime() {
1158         ZonedDateTime base = ZonedDateTime.of(TEST_PARIS_OVERLAP_2008_10_26_02_30, ZONE_PARIS);
1159         ZonedDateTime test = base.with(LocalTime.of(2, 29));
1160         check(test, 2008, 10, 26, 2, 29, 0, 0, OFFSET_0200, ZONE_PARIS);
1161     }
1162 
1163     @Test
1164     public void test_with_adjuster_Year() {
1165         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1166         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1167         ZonedDateTime test = base.with(Year.of(2007));
1168         assertEquals(test, ZonedDateTime.of(ldt.withYear(2007), ZONE_0100));
1169     }
1170 
1171     @Test
1172     public void test_with_adjuster_Month_adjustedDayOfMonth() {
1173         ZonedDateTime base = ZonedDateTime.of(LocalDateTime.of(2012, 7, 31, 0, 0), ZONE_PARIS);
1174         ZonedDateTime test = base.with(Month.JUNE);
1175         check(test, 2012, 6, 30, 0, 0, 0, 0, OFFSET_0200, ZONE_PARIS);
1176     }
1177 
1178     @Test
1179     public void test_with_adjuster_Offset_same() {
1180         ZonedDateTime base = ZonedDateTime.of(LocalDateTime.of(2012, 7, 31, 0, 0), ZONE_PARIS);
1181         ZonedDateTime test = base.with(ZoneOffset.ofHours(2));
1182         check(test, 2012, 7, 31, 0, 0, 0, 0, OFFSET_0200, ZONE_PARIS);
1183     }
1184 
1185     @Test
1186     public void test_with_adjuster_Offset_timeAdjust() {
1187         ZonedDateTime base = ZonedDateTime.of(LocalDateTime.of(2012, 7, 31, 0, 0), ZONE_PARIS);
1188         ZonedDateTime test = base.with(ZoneOffset.ofHours(1));
1189         check(test, 2012, 7, 31, 0, 0, 0, 0, OFFSET_0200, ZONE_PARIS);  // invalid offset ignored
1190     }
1191 
1192     @Test
1193     public void test_with_adjuster_LocalDate_retainOffset1() {
1194         ZoneId newYork = ZoneId.of("America/New_York");
1195         LocalDateTime ldt = LocalDateTime.of(2008, 11, 1, 1, 30);
1196         ZonedDateTime base = ZonedDateTime.of(ldt, newYork);
1197         assertEquals(base.getOffset(), ZoneOffset.ofHours(-4));
1198         ZonedDateTime test = base.with(LocalDate.of(2008, 11, 2));
1199         assertEquals(test.getOffset(), ZoneOffset.ofHours(-4));
1200     }
1201 
1202     @Test
1203     public void test_with_adjuster_LocalDate_retainOffset2() {
1204         ZoneId newYork = ZoneId.of("America/New_York");
1205         LocalDateTime ldt = LocalDateTime.of(2008, 11, 3, 1, 30);
1206         ZonedDateTime base = ZonedDateTime.of(ldt, newYork);
1207         assertEquals(base.getOffset(), ZoneOffset.ofHours(-5));
1208         ZonedDateTime test = base.with(LocalDate.of(2008, 11, 2));
1209         assertEquals(test.getOffset(), ZoneOffset.ofHours(-5));
1210     }
1211 
1212     @Test
1213     public void test_with_adjuster_OffsetDateTime_validOffsetNotInOverlap() {
1214         // ODT will be a valid ZDT for the zone, so must be retained exactly
1215         OffsetDateTime odt = TEST_LOCAL_2008_06_30_11_30_59_500.atOffset(OFFSET_0200);
1216         ZonedDateTime zdt = TEST_PARIS_OVERLAP_2008_10_26_02_30.atZone(ZONE_PARIS);
1217         ZonedDateTime test = zdt.with(odt);
1218         assertEquals(test.toOffsetDateTime(), odt);
1219     }
1220 
1221     @Test
1222     public void test_with_adjuster_OffsetDateTime_invalidOffsetIgnored() {
1223         // ODT has invalid offset for ZDT, so only LDT is set
1224         OffsetDateTime odt = TEST_LOCAL_2008_06_30_11_30_59_500.atOffset(OFFSET_0130);
1225         ZonedDateTime zdt = TEST_PARIS_OVERLAP_2008_10_26_02_30.atZone(ZONE_PARIS);
1226         ZonedDateTime test = zdt.with(odt);
1227         assertEquals(test.toLocalDateTime(), TEST_LOCAL_2008_06_30_11_30_59_500);
1228         assertEquals(test.getOffset(), zdt.getOffset());
1229     }
1230 
1231     @Test
1232     public void test_with_adjuster_OffsetDateTime_retainOffsetInOverlap1() {
1233         // ODT will be a valid ZDT for the zone, so must be retained exactly
1234         OffsetDateTime odt = TEST_PARIS_OVERLAP_2008_10_26_02_30.atOffset(OFFSET_0100);
1235         ZonedDateTime zdt = TEST_LOCAL_2008_06_30_11_30_59_500.atZone(ZONE_PARIS);
1236         ZonedDateTime test = zdt.with(odt);
1237         assertEquals(test.toOffsetDateTime(), odt);
1238     }
1239 
1240     @Test
1241     public void test_with_adjuster_OffsetDateTime_retainOffsetInOverlap2() {
1242         // ODT will be a valid ZDT for the zone, so must be retained exactly
1243         OffsetDateTime odt = TEST_PARIS_OVERLAP_2008_10_26_02_30.atOffset(OFFSET_0200);
1244         ZonedDateTime zdt = TEST_LOCAL_2008_06_30_11_30_59_500.atZone(ZONE_PARIS);
1245         ZonedDateTime test = zdt.with(odt);
1246         assertEquals(test.toOffsetDateTime(), odt);
1247     }
1248 
1249     @Test
1250     public void test_with_adjuster_OffsetTime_validOffsetNotInOverlap() {
1251         // OT has valid offset for resulting time
1252         OffsetTime ot = OffsetTime.of(15, 50, 30, 40, OFFSET_0100);
1253         ZonedDateTime zdt = TEST_PARIS_OVERLAP_2008_10_26_02_30.atZone(ZONE_PARIS);
1254         ZonedDateTime test = zdt.with(ot);
1255         assertEquals(test.toLocalDateTime(), dateTime(2008, 10, 26, 15, 50, 30, 40));
1256         assertEquals(test.getOffset(), OFFSET_0100);
1257     }
1258 
1259     @Test
1260     public void test_with_adjuster_OffsetTime_invalidOffsetIgnored1() {
1261         // OT has invalid offset for ZDT, so only LT is set
1262         OffsetTime ot = OffsetTime.of(0, 50, 30, 40, OFFSET_0130);
1263         ZonedDateTime zdt = dateTime(2008, 10, 26, 2, 30, 0, 0, OFFSET_0200, ZONE_PARIS);  // earlier part of overlap
1264         ZonedDateTime test = zdt.with(ot);
1265         assertEquals(test.toLocalDateTime(), dateTime(2008, 10, 26, 0, 50, 30, 40));
1266         assertEquals(test.getOffset(), OFFSET_0200);  // offset not adjusted
1267     }
1268 
1269     @Test
1270     public void test_with_adjuster_OffsetTime_invalidOffsetIgnored2() {
1271         // OT has invalid offset for ZDT, so only LT is set
1272         OffsetTime ot = OffsetTime.of(15, 50, 30, 40, OFFSET_0130);
1273         ZonedDateTime zdt = dateTime(2008, 10, 26, 2, 30, 0, 0, OFFSET_0200, ZONE_PARIS);  // earlier part of overlap
1274         ZonedDateTime test = zdt.with(ot);
1275         assertEquals(test.toLocalDateTime(), dateTime(2008, 10, 26, 15, 50, 30, 40));
1276         assertEquals(test.getOffset(), OFFSET_0100);  // offset adjusted because of time change
1277     }
1278 
1279     @Test
1280     public void test_with_adjuster_OffsetTime_validOffsetIntoOverlap1() {
1281         // OT has valid offset for resulting time
1282         OffsetTime ot = OffsetTime.of(2, 30, 30, 40, OFFSET_0100);  // valid offset in overlap
1283         ZonedDateTime zdt = dateTime(2008, 10, 26, 0, 0, 0, 0, OFFSET_0200, ZONE_PARIS);  // just before overlap
1284         ZonedDateTime test = zdt.with(ot);
1285         assertEquals(test.toLocalDateTime(), dateTime(2008, 10, 26, 2, 30, 30, 40));
1286         assertEquals(test.getOffset(), OFFSET_0100);
1287     }
1288 
1289     @Test
1290     public void test_with_adjuster_OffsetTime_validOffsetIntoOverlap2() {
1291         // OT has valid offset for resulting time
1292         OffsetTime ot = OffsetTime.of(2, 30, 30, 40, OFFSET_0200);  // valid offset in overlap
1293         ZonedDateTime zdt = dateTime(2008, 10, 26, 0, 0, 0, 0, OFFSET_0200, ZONE_PARIS);  // just before overlap
1294         ZonedDateTime test = zdt.with(ot);
1295         assertEquals(test.toLocalDateTime(), dateTime(2008, 10, 26, 2, 30, 30, 40));
1296         assertEquals(test.getOffset(), OFFSET_0200);
1297     }
1298 
1299     @Test(expectedExceptions=NullPointerException.class)
1300     public void test_with_adjuster_null() {
1301         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1302         base.with((TemporalAdjuster) null);
1303     }
1304 
1305     //-----------------------------------------------------------------------
1306     // with(long,TemporalUnit)
1307     //-----------------------------------------------------------------------
1308     @DataProvider(name = "withFieldLong")
1309     Object[][] data_withFieldLong() {
1310         return new Object[][] {
1311                 // set simple fields
1312                 {TEST_LOCAL_2008_06_30_11_30_59_500.atZone(ZONE_PARIS), YEAR, 2009,
1313                         dateTime(2009, 6, 30, 11, 30, 59, 500, OFFSET_0200, ZONE_PARIS)},
1314                 {TEST_LOCAL_2008_06_30_11_30_59_500.atZone(ZONE_PARIS), MONTH_OF_YEAR, 7,
1315                         dateTime(2008, 7, 30, 11, 30, 59, 500, OFFSET_0200, ZONE_PARIS)},
1316                 {TEST_LOCAL_2008_06_30_11_30_59_500.atZone(ZONE_PARIS), DAY_OF_MONTH, 15,
1317                         dateTime(2008, 6, 15, 11, 30, 59, 500, OFFSET_0200, ZONE_PARIS)},
1318                 {TEST_LOCAL_2008_06_30_11_30_59_500.atZone(ZONE_PARIS), HOUR_OF_DAY, 14,
1319                         dateTime(2008, 6, 30, 14, 30, 59, 500, OFFSET_0200, ZONE_PARIS)},
1320 
1321                 // set around overlap
1322                 {TEST_PARIS_OVERLAP_2008_10_26_02_30.atZone(ZONE_PARIS).withEarlierOffsetAtOverlap(), HOUR_OF_DAY, 0,
1323                         dateTime(2008, 10, 26, 0, 30, 0, 0, OFFSET_0200, ZONE_PARIS)},
1324                 {TEST_PARIS_OVERLAP_2008_10_26_02_30.atZone(ZONE_PARIS).withLaterOffsetAtOverlap(), HOUR_OF_DAY, 0,
1325                         dateTime(2008, 10, 26, 0, 30, 0, 0, OFFSET_0200, ZONE_PARIS)},
1326                 {TEST_PARIS_OVERLAP_2008_10_26_02_30.atZone(ZONE_PARIS).withEarlierOffsetAtOverlap(), MINUTE_OF_HOUR, 20,
1327                         dateTime(2008, 10, 26, 2, 20, 0, 0, OFFSET_0200, ZONE_PARIS)},  // offset unchanged
1328                 {TEST_PARIS_OVERLAP_2008_10_26_02_30.atZone(ZONE_PARIS).withLaterOffsetAtOverlap(), MINUTE_OF_HOUR, 20,
1329                         dateTime(2008, 10, 26, 2, 20, 0, 0, OFFSET_0100, ZONE_PARIS)},  // offset unchanged
1330                 {TEST_PARIS_OVERLAP_2008_10_26_02_30.atZone(ZONE_PARIS).withEarlierOffsetAtOverlap(), HOUR_OF_DAY, 3,
1331                         dateTime(2008, 10, 26, 3, 30, 0, 0, OFFSET_0100, ZONE_PARIS)},
1332                 {TEST_PARIS_OVERLAP_2008_10_26_02_30.atZone(ZONE_PARIS).withLaterOffsetAtOverlap(), HOUR_OF_DAY, 3,
1333                         dateTime(2008, 10, 26, 3, 30, 0, 0, OFFSET_0100, ZONE_PARIS)},
1334 
1335                 // set offset
1336                 {TEST_LOCAL_2008_06_30_11_30_59_500.atZone(ZONE_PARIS), OFFSET_SECONDS, 7200,
1337                         dateTime(2008, 6, 30, 11, 30, 59, 500, OFFSET_0200, ZONE_PARIS)},  // offset unchanged
1338                 {TEST_LOCAL_2008_06_30_11_30_59_500.atZone(ZONE_PARIS), OFFSET_SECONDS, 3600,
1339                         dateTime(2008, 6, 30, 11, 30, 59, 500, OFFSET_0200, ZONE_PARIS)},  // invalid offset ignored
1340                 {TEST_PARIS_OVERLAP_2008_10_26_02_30.atZone(ZONE_PARIS).withEarlierOffsetAtOverlap(), OFFSET_SECONDS, 3600,
1341                         dateTime(2008, 10, 26, 2, 30, 0, 0, OFFSET_0100, ZONE_PARIS)},
1342                 {TEST_PARIS_OVERLAP_2008_10_26_02_30.atZone(ZONE_PARIS).withLaterOffsetAtOverlap(), OFFSET_SECONDS, 3600,
1343                         dateTime(2008, 10, 26, 2, 30, 0, 0, OFFSET_0100, ZONE_PARIS)},
1344                 {TEST_PARIS_OVERLAP_2008_10_26_02_30.atZone(ZONE_PARIS).withEarlierOffsetAtOverlap(), OFFSET_SECONDS, 7200,
1345                         dateTime(2008, 10, 26, 2, 30, 0, 0, OFFSET_0200, ZONE_PARIS)},
1346                 {TEST_PARIS_OVERLAP_2008_10_26_02_30.atZone(ZONE_PARIS).withLaterOffsetAtOverlap(), OFFSET_SECONDS, 7200,
1347                         dateTime(2008, 10, 26, 2, 30, 0, 0, OFFSET_0200, ZONE_PARIS)},
1348         };
1349     };
1350 
1351     @Test(dataProvider = "withFieldLong")
1352     public void test_with_fieldLong(ZonedDateTime base, TemporalField setField, int setValue, ZonedDateTime expected) {
1353         assertEquals(base.with(setField, setValue), expected);
1354     }
1355 
1356     @Test(dataProvider = "withFieldLong")
1357     public void test_with_adjuster_ensureZoneOffsetConsistent(ZonedDateTime base, TemporalField setField, int setValue, ZonedDateTime expected) {
1358         if (setField == OFFSET_SECONDS) {
1359             assertEquals(base.with(ZoneOffset.ofTotalSeconds(setValue)), expected);
1360         }
1361     }
1362 
1363     @Test(dataProvider = "withFieldLong")
1364     public void test_with_adjuster_ensureOffsetDateTimeConsistent(ZonedDateTime base, TemporalField setField, int setValue, ZonedDateTime expected) {
1365         if (setField == OFFSET_SECONDS) {
1366             OffsetDateTime odt = base.toOffsetDateTime().with(setField, setValue);
1367             assertEquals(base.with(odt), expected);
1368         }
1369     }
1370 
1371     //-----------------------------------------------------------------------
1372     // withYear()
1373     //-----------------------------------------------------------------------
1374     @Test
1375     public void test_withYear_normal() {
1376         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1377         ZonedDateTime test = base.withYear(2007);
1378         assertEquals(test, ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500.withYear(2007), ZONE_0100));
1379     }
1380 
1381     @Test
1382     public void test_withYear_noChange() {
1383         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1384         ZonedDateTime test = base.withYear(2008);
1385         assertEquals(test, base);
1386     }
1387 
1388     //-----------------------------------------------------------------------
1389     // with(Month)
1390     //-----------------------------------------------------------------------
1391     @Test
1392     public void test_withMonth_Month_normal() {
1393         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1394         ZonedDateTime test = base.with(JANUARY);
1395         assertEquals(test, ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500.withMonth(1), ZONE_0100));
1396     }
1397 
1398     @Test(expectedExceptions = NullPointerException.class)
1399     public void test_withMonth_Month_null() {
1400         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1401         base.with((Month) null);
1402     }
1403 
1404     //-----------------------------------------------------------------------
1405     // withMonth()
1406     //-----------------------------------------------------------------------
1407     @Test
1408     public void test_withMonth_normal() {
1409         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1410         ZonedDateTime test = base.withMonth(1);
1411         assertEquals(test, ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500.withMonth(1), ZONE_0100));
1412     }
1413 
1414     @Test
1415     public void test_withMonth_noChange() {
1416         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1417         ZonedDateTime test = base.withMonth(6);
1418         assertEquals(test, base);
1419     }
1420 
1421     @Test(expectedExceptions=DateTimeException.class)
1422     public void test_withMonth_tooBig() {
1423         TEST_DATE_TIME.withMonth(13);
1424     }
1425 
1426     @Test(expectedExceptions=DateTimeException.class)
1427     public void test_withMonth_tooSmall() {
1428         TEST_DATE_TIME.withMonth(0);
1429     }
1430 
1431     //-----------------------------------------------------------------------
1432     // withDayOfMonth()
1433     //-----------------------------------------------------------------------
1434     @Test
1435     public void test_withDayOfMonth_normal() {
1436         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1437         ZonedDateTime test = base.withDayOfMonth(15);
1438         assertEquals(test, ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500.withDayOfMonth(15), ZONE_0100));
1439     }
1440 
1441     @Test
1442     public void test_withDayOfMonth_noChange() {
1443         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1444         ZonedDateTime test = base.withDayOfMonth(30);
1445         assertEquals(test, base);
1446     }
1447 
1448     @Test(expectedExceptions=DateTimeException.class)
1449     public void test_withDayOfMonth_tooBig() {
1450         LocalDateTime.of(2007, 7, 2, 11, 30).atZone(ZONE_PARIS).withDayOfMonth(32);
1451     }
1452 
1453     @Test(expectedExceptions=DateTimeException.class)
1454     public void test_withDayOfMonth_tooSmall() {
1455         TEST_DATE_TIME.withDayOfMonth(0);
1456     }
1457 
1458     @Test(expectedExceptions=DateTimeException.class)
1459     public void test_withDayOfMonth_invalid31() {
1460         LocalDateTime.of(2007, 6, 2, 11, 30).atZone(ZONE_PARIS).withDayOfMonth(31);
1461     }
1462 
1463     //-----------------------------------------------------------------------
1464     // withDayOfYear()
1465     //-----------------------------------------------------------------------
1466     @Test
1467     public void test_withDayOfYear_normal() {
1468         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1469         ZonedDateTime test = base.withDayOfYear(33);
1470         assertEquals(test, ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500.withDayOfYear(33), ZONE_0100));
1471     }
1472 
1473     @Test
1474     public void test_withDayOfYear_noChange() {
1475         LocalDateTime ldt = LocalDateTime.of(2008, 2, 5, 23, 30, 59, 0);
1476         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1477         ZonedDateTime test = base.withDayOfYear(36);
1478         assertEquals(test, base);
1479     }
1480 
1481     @Test(expectedExceptions=DateTimeException.class)
1482     public void test_withDayOfYear_tooBig() {
1483         TEST_DATE_TIME.withDayOfYear(367);
1484     }
1485 
1486     @Test(expectedExceptions=DateTimeException.class)
1487     public void test_withDayOfYear_tooSmall() {
1488         TEST_DATE_TIME.withDayOfYear(0);
1489     }
1490 
1491     @Test(expectedExceptions=DateTimeException.class)
1492     public void test_withDayOfYear_invalid366() {
1493         LocalDateTime.of(2007, 2, 2, 11, 30).atZone(ZONE_PARIS).withDayOfYear(366);
1494     }
1495 
1496     //-----------------------------------------------------------------------
1497     // withHour()
1498     //-----------------------------------------------------------------------
1499     @Test
1500     public void test_withHour_normal() {
1501         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1502         ZonedDateTime test = base.withHour(15);
1503         assertEquals(test, ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500.withHour(15), ZONE_0100));
1504     }
1505 
1506     @Test
1507     public void test_withHour_noChange() {
1508         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1509         ZonedDateTime test = base.withHour(11);
1510         assertEquals(test, base);
1511     }
1512 
1513     //-----------------------------------------------------------------------
1514     // withMinute()
1515     //-----------------------------------------------------------------------
1516     @Test
1517     public void test_withMinute_normal() {
1518         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1519         ZonedDateTime test = base.withMinute(15);
1520         assertEquals(test, ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500.withMinute(15), ZONE_0100));
1521     }
1522 
1523     @Test
1524     public void test_withMinute_noChange() {
1525         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1526         ZonedDateTime test = base.withMinute(30);
1527         assertEquals(test, base);
1528     }
1529 
1530     //-----------------------------------------------------------------------
1531     // withSecond()
1532     //-----------------------------------------------------------------------
1533     @Test
1534     public void test_withSecond_normal() {
1535         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1536         ZonedDateTime test = base.withSecond(12);
1537         assertEquals(test, ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500.withSecond(12), ZONE_0100));
1538     }
1539 
1540     @Test
1541     public void test_withSecond_noChange() {
1542         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1543         ZonedDateTime test = base.withSecond(59);
1544         assertEquals(test, base);
1545     }
1546 
1547     //-----------------------------------------------------------------------
1548     // withNano()
1549     //-----------------------------------------------------------------------
1550     @Test
1551     public void test_withNanoOfSecond_normal() {
1552         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1553         ZonedDateTime test = base.withNano(15);
1554         assertEquals(test, ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500.withNano(15), ZONE_0100));
1555     }
1556 
1557     @Test
1558     public void test_withNanoOfSecond_noChange() {
1559         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1560         ZonedDateTime test = base.withNano(500);
1561         assertEquals(test, base);
1562     }
1563 
1564     //-----------------------------------------------------------------------
1565     // truncatedTo(TemporalUnit)
1566     //-----------------------------------------------------------------------
1567     @Test
1568     public void test_truncatedTo_normal() {
1569         assertEquals(TEST_DATE_TIME.truncatedTo(NANOS), TEST_DATE_TIME);
1570         assertEquals(TEST_DATE_TIME.truncatedTo(SECONDS), TEST_DATE_TIME.withNano(0));
1571         assertEquals(TEST_DATE_TIME.truncatedTo(DAYS), TEST_DATE_TIME.with(LocalTime.MIDNIGHT));
1572     }
1573 
1574     @Test(expectedExceptions=NullPointerException.class)
1575     public void test_truncatedTo_null() {
1576         TEST_DATE_TIME.truncatedTo(null);
1577     }
1578 
1579     //-----------------------------------------------------------------------
1580     // plus/minus
1581     //-----------------------------------------------------------------------
1582     @DataProvider(name="plusDays")
1583     Object[][] data_plusDays() {
1584         return new Object[][] {
1585             // normal
1586             {dateTime(2008, 6, 30, 23, 30, 59, 0, OFFSET_0100, ZONE_0100), 0, dateTime(2008, 6, 30, 23, 30, 59, 0, OFFSET_0100, ZONE_0100)},
1587             {dateTime(2008, 6, 30, 23, 30, 59, 0, OFFSET_0100, ZONE_0100), 1, dateTime(2008, 7, 1, 23, 30, 59, 0, OFFSET_0100, ZONE_0100)},
1588             {dateTime(2008, 6, 30, 23, 30, 59, 0, OFFSET_0100, ZONE_0100), -1, dateTime(2008, 6, 29, 23, 30, 59, 0, OFFSET_0100, ZONE_0100)},
1589             // skip over gap
1590             {dateTime(2008, 3, 30, 1, 30, 0, 0, OFFSET_0100, ZONE_PARIS), 1, dateTime(2008, 3, 31, 1, 30, 0, 0, OFFSET_0200, ZONE_PARIS)},
1591             {dateTime(2008, 3, 30, 3, 30, 0, 0, OFFSET_0200, ZONE_PARIS), -1, dateTime(2008, 3, 29, 3, 30, 0, 0, OFFSET_0100, ZONE_PARIS)},
1592             // land in gap
1593             {dateTime(2008, 3, 29, 2, 30, 0, 0, OFFSET_0100, ZONE_PARIS), 1, dateTime(2008, 3, 30, 3, 30, 0, 0, OFFSET_0200, ZONE_PARIS)},
1594             {dateTime(2008, 3, 31, 2, 30, 0, 0, OFFSET_0200, ZONE_PARIS), -1, dateTime(2008, 3, 30, 3, 30, 0, 0, OFFSET_0200, ZONE_PARIS)},
1595             // skip over overlap
1596             {dateTime(2008, 10, 26, 1, 30, 0, 0, OFFSET_0200, ZONE_PARIS), 1, dateTime(2008, 10, 27, 1, 30, 0, 0, OFFSET_0100, ZONE_PARIS)},
1597             {dateTime(2008, 10, 25, 3, 30, 0, 0, OFFSET_0200, ZONE_PARIS), 1, dateTime(2008, 10, 26, 3, 30, 0, 0, OFFSET_0100, ZONE_PARIS)},
1598             // land in overlap
1599             {dateTime(2008, 10, 25, 2, 30, 0, 0, OFFSET_0200, ZONE_PARIS), 1, dateTime(2008, 10, 26, 2, 30, 0, 0, OFFSET_0200, ZONE_PARIS)},
1600             {dateTime(2008, 10, 27, 2, 30, 0, 0, OFFSET_0100, ZONE_PARIS), -1, dateTime(2008, 10, 26, 2, 30, 0, 0, OFFSET_0100, ZONE_PARIS)},
1601         };
1602     }
1603 
1604     @DataProvider(name="plusTime")
1605     Object[][] data_plusTime() {
1606         return new Object[][] {
1607             // normal
1608             {dateTime(2008, 6, 30, 23, 30, 59, 0, OFFSET_0100, ZONE_0100), 0, dateTime(2008, 6, 30, 23, 30, 59, 0, OFFSET_0100, ZONE_0100)},
1609             {dateTime(2008, 6, 30, 23, 30, 59, 0, OFFSET_0100, ZONE_0100), 1, dateTime(2008, 7, 1, 0, 30, 59, 0, OFFSET_0100, ZONE_0100)},
1610             {dateTime(2008, 6, 30, 23, 30, 59, 0, OFFSET_0100, ZONE_0100), -1, dateTime(2008, 6, 30, 22, 30, 59, 0, OFFSET_0100, ZONE_0100)},
1611             // gap
1612             {dateTime(2008, 3, 30, 1, 30, 0, 0, OFFSET_0100, ZONE_PARIS), 1, dateTime(2008, 3, 30, 3, 30, 0, 0, OFFSET_0200, ZONE_PARIS)},
1613             {dateTime(2008, 3, 30, 3, 30, 0, 0, OFFSET_0200, ZONE_PARIS), -1, dateTime(2008, 3, 30, 1, 30, 0, 0, OFFSET_0100, ZONE_PARIS)},
1614             // overlap
1615             {dateTime(2008, 10, 26, 1, 30, 0, 0, OFFSET_0200, ZONE_PARIS), 1, dateTime(2008, 10, 26, 2, 30, 0, 0, OFFSET_0200, ZONE_PARIS)},
1616             {dateTime(2008, 10, 26, 1, 30, 0, 0, OFFSET_0200, ZONE_PARIS), 2, dateTime(2008, 10, 26, 2, 30, 0, 0, OFFSET_0100, ZONE_PARIS)},
1617             {dateTime(2008, 10, 26, 1, 30, 0, 0, OFFSET_0200, ZONE_PARIS), 3, dateTime(2008, 10, 26, 3, 30, 0, 0, OFFSET_0100, ZONE_PARIS)},
1618             {dateTime(2008, 10, 26, 2, 30, 0, 0, OFFSET_0200, ZONE_PARIS), 1, dateTime(2008, 10, 26, 2, 30, 0, 0, OFFSET_0100, ZONE_PARIS)},
1619             {dateTime(2008, 10, 26, 2, 30, 0, 0, OFFSET_0200, ZONE_PARIS), 2, dateTime(2008, 10, 26, 3, 30, 0, 0, OFFSET_0100, ZONE_PARIS)},
1620         };
1621     }
1622 
1623     //-----------------------------------------------------------------------
1624     // plus(TemporalAmount)
1625     //-----------------------------------------------------------------------
1626     @Test(dataProvider="plusDays")
1627     public void test_plus_TemporalAmount_Period_days(ZonedDateTime base, int amount, ZonedDateTime expected) {
1628         assertEquals(base.plus(Period.ofDays(amount)), expected);
1629     }
1630 
1631     @Test(dataProvider="plusTime")
1632     public void test_plus_TemporalAmount_Period_hours(ZonedDateTime base, long amount, ZonedDateTime expected) {
1633         assertEquals(base.plus(MockSimplePeriod.of(amount, HOURS)), expected);
1634     }
1635 
1636     @Test(dataProvider="plusTime")
1637     public void test_plus_TemporalAmount_Duration_hours(ZonedDateTime base, long amount, ZonedDateTime expected) {
1638         assertEquals(base.plus(Duration.ofHours(amount)), expected);
1639     }
1640 
1641     @Test
1642     public void test_plus_TemporalAmount() {
1643         MockSimplePeriod period = MockSimplePeriod.of(7, ChronoUnit.MONTHS);
1644         ZonedDateTime t = ZonedDateTime.of(LocalDateTime.of(2008, 6, 1, 12, 30, 59, 500), ZONE_0100);
1645         ZonedDateTime expected = ZonedDateTime.of(LocalDateTime.of(2009, 1, 1, 12, 30, 59, 500), ZONE_0100);
1646         assertEquals(t.plus(period), expected);
1647     }
1648 
1649     @Test
1650     public void test_plus_TemporalAmount_Duration() {
1651         Duration duration = Duration.ofSeconds(4L * 60 * 60 + 5L * 60 + 6L);
1652         ZonedDateTime t = ZonedDateTime.of(LocalDateTime.of(2008, 6, 1, 12, 30, 59, 500), ZONE_0100);
1653         ZonedDateTime expected = ZonedDateTime.of(LocalDateTime.of(2008, 6, 1, 16, 36, 5, 500), ZONE_0100);
1654         assertEquals(t.plus(duration), expected);
1655     }
1656 
1657     @Test
1658     public void test_plus_TemporalAmount_Period_zero() {
1659         ZonedDateTime t = TEST_DATE_TIME.plus(MockSimplePeriod.ZERO_DAYS);
1660         assertEquals(t, TEST_DATE_TIME);
1661     }
1662 
1663     @Test
1664     public void test_plus_TemporalAmount_Duration_zero() {
1665         ZonedDateTime t = TEST_DATE_TIME.plus(Duration.ZERO);
1666         assertEquals(t, TEST_DATE_TIME);
1667     }
1668 
1669     @Test(expectedExceptions=NullPointerException.class)
1670     public void test_plus_TemporalAmount_null() {
1671         TEST_DATE_TIME.plus((TemporalAmount) null);
1672     }
1673 
1674     //-----------------------------------------------------------------------
1675     // plus(long,TemporalUnit)
1676     //-----------------------------------------------------------------------
1677     @Test(dataProvider="plusDays")
1678     public void test_plus_longUnit_days(ZonedDateTime base, long amount, ZonedDateTime expected) {
1679         assertEquals(base.plus(amount, DAYS), expected);
1680     }
1681 
1682     @Test(dataProvider="plusTime")
1683     public void test_plus_longUnit_hours(ZonedDateTime base, long amount, ZonedDateTime expected) {
1684         assertEquals(base.plus(amount, HOURS), expected);
1685     }
1686 
1687     @Test(dataProvider="plusTime")
1688     public void test_plus_longUnit_minutes(ZonedDateTime base, long amount, ZonedDateTime expected) {
1689         assertEquals(base.plus(amount * 60, MINUTES), expected);
1690     }
1691 
1692     @Test(dataProvider="plusTime")
1693     public void test_plus_longUnit_seconds(ZonedDateTime base, long amount, ZonedDateTime expected) {
1694         assertEquals(base.plus(amount * 3600, SECONDS), expected);
1695     }
1696 
1697     @Test(dataProvider="plusTime")
1698     public void test_plus_longUnit_nanos(ZonedDateTime base, long amount, ZonedDateTime expected) {
1699         assertEquals(base.plus(amount * 3600_000_000_000L, NANOS), expected);
1700     }
1701 
1702     @Test(expectedExceptions=NullPointerException.class)
1703     public void test_plus_longUnit_null() {
1704         TEST_DATE_TIME_PARIS.plus(0, null);
1705     }
1706 
1707     //-----------------------------------------------------------------------
1708     // plusYears()
1709     //-----------------------------------------------------------------------
1710     @Test
1711     public void test_plusYears() {
1712         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1713         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1714         ZonedDateTime test = base.plusYears(1);
1715         assertEquals(test, ZonedDateTime.of(ldt.plusYears(1), ZONE_0100));
1716     }
1717 
1718     @Test
1719     public void test_plusYears_zero() {
1720         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1721         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1722         ZonedDateTime test = base.plusYears(0);
1723         assertEquals(test, base);
1724     }
1725 
1726     //-----------------------------------------------------------------------
1727     // plusMonths()
1728     //-----------------------------------------------------------------------
1729     @Test
1730     public void test_plusMonths() {
1731         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1732         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1733         ZonedDateTime test = base.plusMonths(1);
1734         assertEquals(test, ZonedDateTime.of(ldt.plusMonths(1), ZONE_0100));
1735     }
1736 
1737     @Test
1738     public void test_plusMonths_zero() {
1739         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1740         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1741         ZonedDateTime test = base.plusMonths(0);
1742         assertEquals(test, base);
1743     }
1744 
1745     //-----------------------------------------------------------------------
1746     // plusWeeks()
1747     //-----------------------------------------------------------------------
1748     @Test
1749     public void test_plusWeeks() {
1750         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1751         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1752         ZonedDateTime test = base.plusWeeks(1);
1753         assertEquals(test, ZonedDateTime.of(ldt.plusWeeks(1), ZONE_0100));
1754     }
1755 
1756     @Test
1757     public void test_plusWeeks_zero() {
1758         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1759         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1760         ZonedDateTime test = base.plusWeeks(0);
1761         assertEquals(test, base);
1762     }
1763 
1764     //-----------------------------------------------------------------------
1765     // plusDays()
1766     //-----------------------------------------------------------------------
1767     @Test(dataProvider="plusDays")
1768     public void test_plusDays(ZonedDateTime base, long amount, ZonedDateTime expected) {
1769         assertEquals(base.plusDays(amount), expected);
1770     }
1771 
1772     //-----------------------------------------------------------------------
1773     // plusHours()
1774     //-----------------------------------------------------------------------
1775     @Test(dataProvider="plusTime")
1776     public void test_plusHours(ZonedDateTime base, long amount, ZonedDateTime expected) {
1777         assertEquals(base.plusHours(amount), expected);
1778     }
1779 
1780     //-----------------------------------------------------------------------
1781     // plusMinutes()
1782     //-----------------------------------------------------------------------
1783     @Test(dataProvider="plusTime")
1784     public void test_plusMinutes(ZonedDateTime base, long amount, ZonedDateTime expected) {
1785         assertEquals(base.plusMinutes(amount * 60), expected);
1786     }
1787 
1788     @Test
1789     public void test_plusMinutes_minutes() {
1790         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1791         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1792         ZonedDateTime test = base.plusMinutes(30);
1793         assertEquals(test, ZonedDateTime.of(ldt.plusMinutes(30), ZONE_0100));
1794     }
1795 
1796     //-----------------------------------------------------------------------
1797     // plusSeconds()
1798     //-----------------------------------------------------------------------
1799     @Test(dataProvider="plusTime")
1800     public void test_plusSeconds(ZonedDateTime base, long amount, ZonedDateTime expected) {
1801         assertEquals(base.plusSeconds(amount * 3600), expected);
1802     }
1803 
1804     @Test
1805     public void test_plusSeconds_seconds() {
1806         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1807         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1808         ZonedDateTime test = base.plusSeconds(1);
1809         assertEquals(test, ZonedDateTime.of(ldt.plusSeconds(1), ZONE_0100));
1810     }
1811 
1812     //-----------------------------------------------------------------------
1813     // plusNanos()
1814     //-----------------------------------------------------------------------
1815     @Test(dataProvider="plusTime")
1816     public void test_plusNanos(ZonedDateTime base, long amount, ZonedDateTime expected) {
1817         assertEquals(base.plusNanos(amount * 3600_000_000_000L), expected);
1818     }
1819 
1820     @Test
1821     public void test_plusNanos_nanos() {
1822         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1823         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1824         ZonedDateTime test = base.plusNanos(1);
1825         assertEquals(test, ZonedDateTime.of(ldt.plusNanos(1), ZONE_0100));
1826     }
1827 
1828     //-----------------------------------------------------------------------
1829     // minus(TemporalAmount)
1830     //-----------------------------------------------------------------------
1831     @Test(dataProvider="plusDays")
1832     public void test_minus_TemporalAmount_Period_days(ZonedDateTime base, int amount, ZonedDateTime expected) {
1833         assertEquals(base.minus(Period.ofDays(-amount)), expected);
1834     }
1835 
1836     @Test(dataProvider="plusTime")
1837     public void test_minus_TemporalAmount_Period_hours(ZonedDateTime base, long amount, ZonedDateTime expected) {
1838         assertEquals(base.minus(MockSimplePeriod.of(-amount, HOURS)), expected);
1839     }
1840 
1841     @Test(dataProvider="plusTime")
1842     public void test_minus_TemporalAmount_Duration_hours(ZonedDateTime base, long amount, ZonedDateTime expected) {
1843         assertEquals(base.minus(Duration.ofHours(-amount)), expected);
1844     }
1845 
1846     @Test
1847     public void test_minus_TemporalAmount() {
1848         MockSimplePeriod period = MockSimplePeriod.of(7, ChronoUnit.MONTHS);
1849         ZonedDateTime t = ZonedDateTime.of(LocalDateTime.of(2008, 6, 1, 12, 30, 59, 500), ZONE_0100);
1850         ZonedDateTime expected = ZonedDateTime.of(LocalDateTime.of(2007, 11, 1, 12, 30, 59, 500), ZONE_0100);
1851         assertEquals(t.minus(period), expected);
1852     }
1853 
1854     @Test
1855     public void test_minus_TemporalAmount_Duration() {
1856         Duration duration = Duration.ofSeconds(4L * 60 * 60 + 5L * 60 + 6L);
1857         ZonedDateTime t = ZonedDateTime.of(LocalDateTime.of(2008, 6, 1, 12, 30, 59, 500), ZONE_0100);
1858         ZonedDateTime expected = ZonedDateTime.of(LocalDateTime.of(2008, 6, 1, 8, 25, 53, 500), ZONE_0100);
1859         assertEquals(t.minus(duration), expected);
1860     }
1861 
1862     @Test
1863     public void test_minus_TemporalAmount_Period_zero() {
1864         ZonedDateTime t = TEST_DATE_TIME.minus(MockSimplePeriod.ZERO_DAYS);
1865         assertEquals(t, TEST_DATE_TIME);
1866     }
1867 
1868     @Test
1869     public void test_minus_TemporalAmount_Duration_zero() {
1870         ZonedDateTime t = TEST_DATE_TIME.minus(Duration.ZERO);
1871         assertEquals(t, TEST_DATE_TIME);
1872     }
1873 
1874     @Test(expectedExceptions=NullPointerException.class)
1875     public void test_minus_TemporalAmount_null() {
1876         TEST_DATE_TIME.minus((TemporalAmount) null);
1877     }
1878 
1879     //-----------------------------------------------------------------------
1880     // minusYears()
1881     //-----------------------------------------------------------------------
1882     @Test
1883     public void test_minusYears() {
1884         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1885         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1886         ZonedDateTime test = base.minusYears(1);
1887         assertEquals(test, ZonedDateTime.of(ldt.minusYears(1), ZONE_0100));
1888     }
1889 
1890     @Test
1891     public void test_minusYears_zero() {
1892         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1893         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1894         ZonedDateTime test = base.minusYears(0);
1895         assertEquals(test, base);
1896     }
1897 
1898     //-----------------------------------------------------------------------
1899     // minusMonths()
1900     //-----------------------------------------------------------------------
1901     @Test
1902     public void test_minusMonths() {
1903         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1904         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1905         ZonedDateTime test = base.minusMonths(1);
1906         assertEquals(test, ZonedDateTime.of(ldt.minusMonths(1), ZONE_0100));
1907     }
1908 
1909     @Test
1910     public void test_minusMonths_zero() {
1911         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1912         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1913         ZonedDateTime test = base.minusMonths(0);
1914         assertEquals(test, base);
1915     }
1916 
1917     //-----------------------------------------------------------------------
1918     // minusWeeks()
1919     //-----------------------------------------------------------------------
1920     @Test
1921     public void test_minusWeeks() {
1922         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1923         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1924         ZonedDateTime test = base.minusWeeks(1);
1925         assertEquals(test, ZonedDateTime.of(ldt.minusWeeks(1), ZONE_0100));
1926     }
1927 
1928     @Test
1929     public void test_minusWeeks_zero() {
1930         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1931         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1932         ZonedDateTime test = base.minusWeeks(0);
1933         assertEquals(test, base);
1934     }
1935 
1936     //-----------------------------------------------------------------------
1937     // minusDays()
1938     //-----------------------------------------------------------------------
1939     @Test(dataProvider="plusDays")
1940     public void test_minusDays(ZonedDateTime base, long amount, ZonedDateTime expected) {
1941         assertEquals(base.minusDays(-amount), expected);
1942     }
1943 
1944     //-----------------------------------------------------------------------
1945     // minusHours()
1946     //-----------------------------------------------------------------------
1947     @Test(dataProvider="plusTime")
1948     public void test_minusHours(ZonedDateTime base, long amount, ZonedDateTime expected) {
1949         assertEquals(base.minusHours(-amount), expected);
1950     }
1951 
1952     //-----------------------------------------------------------------------
1953     // minusMinutes()
1954     //-----------------------------------------------------------------------
1955     @Test(dataProvider="plusTime")
1956     public void test_minusMinutes(ZonedDateTime base, long amount, ZonedDateTime expected) {
1957         assertEquals(base.minusMinutes(-amount * 60), expected);
1958     }
1959 
1960     @Test
1961     public void test_minusMinutes_minutes() {
1962         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1963         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1964         ZonedDateTime test = base.minusMinutes(30);
1965         assertEquals(test, ZonedDateTime.of(ldt.minusMinutes(30), ZONE_0100));
1966     }
1967 
1968     //-----------------------------------------------------------------------
1969     // minusSeconds()
1970     //-----------------------------------------------------------------------
1971     @Test(dataProvider="plusTime")
1972     public void test_minusSeconds(ZonedDateTime base, long amount, ZonedDateTime expected) {
1973         assertEquals(base.minusSeconds(-amount * 3600), expected);
1974     }
1975 
1976     @Test
1977     public void test_minusSeconds_seconds() {
1978         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1979         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1980         ZonedDateTime test = base.minusSeconds(1);
1981         assertEquals(test, ZonedDateTime.of(ldt.minusSeconds(1), ZONE_0100));
1982     }
1983 
1984     //-----------------------------------------------------------------------
1985     // minusNanos()
1986     //-----------------------------------------------------------------------
1987     @Test(dataProvider="plusTime")
1988     public void test_minusNanos(ZonedDateTime base, long amount, ZonedDateTime expected) {
1989         assertEquals(base.minusNanos(-amount * 3600_000_000_000L), expected);
1990     }
1991 
1992     @Test
1993     public void test_minusNanos_nanos() {
1994         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1995         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1996         ZonedDateTime test = base.minusNanos(1);
1997         assertEquals(test, ZonedDateTime.of(ldt.minusNanos(1), ZONE_0100));
1998     }
1999 
2000     //-----------------------------------------------------------------------
2001     // until(Temporal,TemporalUnit)
2002     //-----------------------------------------------------------------------
2003     // TODO: more tests for period between two different zones
2004     // compare results to OffsetDateTime.until, especially wrt dates
2005 
2006     @Test(dataProvider="plusDays")
2007     public void test_until_days(ZonedDateTime base, long expected, ZonedDateTime end) {
2008         if (base.toLocalTime().equals(end.toLocalTime()) == false) {
2009             return;  // avoid DST gap input values
2010         }
2011         assertEquals(base.until(end, DAYS), expected);
2012     }
2013 
2014     @Test(dataProvider="plusTime")
2015     public void test_until_hours(ZonedDateTime base, long expected, ZonedDateTime end) {
2016         assertEquals(base.until(end, HOURS), expected);
2017     }
2018 
2019     @Test(dataProvider="plusTime")
2020     public void test_until_minutes(ZonedDateTime base, long expected, ZonedDateTime end) {
2021         assertEquals(base.until(end, MINUTES), expected * 60);
2022     }
2023 
2024     @Test(dataProvider="plusTime")
2025     public void test_until_seconds(ZonedDateTime base, long expected, ZonedDateTime end) {
2026         assertEquals(base.until(end, SECONDS), expected * 3600);
2027     }
2028 
2029     @Test(dataProvider="plusTime")
2030     public void test_until_nanos(ZonedDateTime base, long expected, ZonedDateTime end) {
2031         assertEquals(base.until(end, NANOS), expected * 3600_000_000_000L);
2032     }
2033 
2034     @Test
2035     public void test_until_parisLondon() {
2036         ZonedDateTime midnightLondon = LocalDate.of(2012, 6, 28).atStartOfDay(ZONE_LONDON);
2037         ZonedDateTime midnightParis1 = LocalDate.of(2012, 6, 29).atStartOfDay(ZONE_PARIS);
2038         ZonedDateTime oneAm1 = LocalDateTime.of(2012, 6, 29, 1, 0).atZone(ZONE_PARIS);
2039         ZonedDateTime midnightParis2 = LocalDate.of(2012, 6, 30).atStartOfDay(ZONE_PARIS);
2040 
2041         assertEquals(midnightLondon.until(midnightParis1, HOURS), 23);
2042         assertEquals(midnightLondon.until(oneAm1, HOURS), 24);
2043         assertEquals(midnightLondon.until(midnightParis2, HOURS), 23 + 24);
2044 
2045         assertEquals(midnightLondon.until(midnightParis1, DAYS), 0);
2046         assertEquals(midnightLondon.until(oneAm1, DAYS), 1);
2047         assertEquals(midnightLondon.until(midnightParis2, DAYS), 1);
2048     }
2049 
2050     @Test
2051     public void test_until_gap() {
2052         ZonedDateTime before = TEST_PARIS_GAP_2008_03_30_02_30.withHour(0).withMinute(0).atZone(ZONE_PARIS);
2053         ZonedDateTime after = TEST_PARIS_GAP_2008_03_30_02_30.withHour(0).withMinute(0).plusDays(1).atZone(ZONE_PARIS);
2054 
2055         assertEquals(before.until(after, HOURS), 23);
2056         assertEquals(before.until(after, DAYS), 1);
2057     }
2058 
2059     @Test
2060     public void test_until_overlap() {
2061         ZonedDateTime before = TEST_PARIS_OVERLAP_2008_10_26_02_30.withHour(0).withMinute(0).atZone(ZONE_PARIS);
2062         ZonedDateTime after = TEST_PARIS_OVERLAP_2008_10_26_02_30.withHour(0).withMinute(0).plusDays(1).atZone(ZONE_PARIS);
2063 
2064         assertEquals(before.until(after, HOURS), 25);
2065         assertEquals(before.until(after, DAYS), 1);
2066     }
2067 
2068     @Test(expectedExceptions=DateTimeException.class)
2069     public void test_until_differentType() {
2070         TEST_DATE_TIME_PARIS.until(TEST_LOCAL_2008_06_30_11_30_59_500, DAYS);
2071     }
2072 
2073     @Test(expectedExceptions=NullPointerException.class)
2074     public void test_until_nullTemporal() {
2075         TEST_DATE_TIME_PARIS.until(null, DAYS);
2076     }
2077 
2078     @Test(expectedExceptions=NullPointerException.class)
2079     public void test_until_nullUnit() {
2080         TEST_DATE_TIME_PARIS.until(TEST_DATE_TIME_PARIS, null);
2081     }
2082 
2083     //-----------------------------------------------------------------------
2084     // format(DateTimeFormatter)
2085     //-----------------------------------------------------------------------
2086     @Test
2087     public void test_format_formatter() {
2088         DateTimeFormatter f = DateTimeFormatter.ofPattern("y M d H m s");
2089         String t = ZonedDateTime.of(dateTime(2010, 12, 3, 11, 30), ZONE_PARIS).format(f);
2090         assertEquals(t, "2010 12 3 11 30 0");
2091     }
2092 
2093     @Test(expectedExceptions=NullPointerException.class)
2094     public void test_format_formatter_null() {
2095         ZonedDateTime.of(dateTime(2010, 12, 3, 11, 30), ZONE_PARIS).format(null);
2096     }
2097 
2098     //-----------------------------------------------------------------------
2099     // toOffsetDateTime()
2100     //-----------------------------------------------------------------------
2101     @Test
2102     public void test_toOffsetDateTime() {
2103         assertEquals(TEST_DATE_TIME.toOffsetDateTime(), OffsetDateTime.of(TEST_DATE_TIME.toLocalDateTime(), TEST_DATE_TIME.getOffset()));
2104     }
2105 
2106     //-----------------------------------------------------------------------
2107     // toInstant()
2108     //-----------------------------------------------------------------------
2109     @DataProvider(name="toInstant")
2110     Object[][] data_toInstant() {
2111         return new Object[][] {
2112             {LocalDateTime.of(1970, 1, 1, 0, 0, 0, 0), 0L, 0},
2113             {LocalDateTime.of(1970, 1, 1, 0, 0, 0, 1), 0L, 1},
2114             {LocalDateTime.of(1970, 1, 1, 0, 0, 0, 999_999_999), 0L, 999_999_999},
2115             {LocalDateTime.of(1970, 1, 1, 0, 0, 1, 0), 1L, 0},
2116             {LocalDateTime.of(1970, 1, 1, 0, 0, 1, 1), 1L, 1},
2117             {LocalDateTime.of(1969, 12, 31, 23, 59, 59, 999999999), -1L, 999_999_999},
2118             {LocalDateTime.of(1970, 1, 2, 0, 0), 24L * 60L * 60L, 0},
2119             {LocalDateTime.of(1969, 12, 31, 0, 0), -24L * 60L * 60L, 0},
2120         };
2121     }
2122 
2123     @Test(dataProvider="toInstant")
2124     public void test_toInstant_UTC(LocalDateTime ldt, long expectedEpSec, int expectedNos) {
2125         ZonedDateTime dt = ldt.atZone(ZoneOffset.UTC);
2126         Instant test = dt.toInstant();
2127         assertEquals(test.getEpochSecond(), expectedEpSec);
2128         assertEquals(test.getNano(), expectedNos);
2129     }
2130 
2131     @Test(dataProvider="toInstant")
2132     public void test_toInstant_P0100(LocalDateTime ldt, long expectedEpSec, int expectedNos) {
2133         ZonedDateTime dt = ldt.atZone(ZONE_0100);
2134         Instant test = dt.toInstant();
2135         assertEquals(test.getEpochSecond(), expectedEpSec - 3600);
2136         assertEquals(test.getNano(), expectedNos);
2137     }
2138 
2139     @Test(dataProvider="toInstant")
2140     public void test_toInstant_M0100(LocalDateTime ldt, long expectedEpSec, int expectedNos) {
2141         ZonedDateTime dt = ldt.atZone(ZONE_M0100);
2142         Instant test = dt.toInstant();
2143         assertEquals(test.getEpochSecond(), expectedEpSec + 3600);
2144         assertEquals(test.getNano(), expectedNos);
2145     }
2146 
2147     //-----------------------------------------------------------------------
2148     // toEpochSecond()
2149     //-----------------------------------------------------------------------
2150     @Test
2151     public void test_toEpochSecond_afterEpoch() {
2152         LocalDateTime ldt = LocalDateTime.of(1970, 1, 1, 0, 0).plusHours(1);
2153         for (int i = 0; i < 100000; i++) {
2154             ZonedDateTime a = ZonedDateTime.of(ldt, ZONE_PARIS);
2155             assertEquals(a.toEpochSecond(), i);
2156             ldt = ldt.plusSeconds(1);
2157         }
2158     }
2159 
2160     @Test
2161     public void test_toEpochSecond_beforeEpoch() {
2162         LocalDateTime ldt = LocalDateTime.of(1970, 1, 1, 0, 0).plusHours(1);
2163         for (int i = 0; i < 100000; i++) {
2164             ZonedDateTime a = ZonedDateTime.of(ldt, ZONE_PARIS);
2165             assertEquals(a.toEpochSecond(), -i);
2166             ldt = ldt.minusSeconds(1);
2167         }
2168     }
2169 
2170     @Test(dataProvider="toInstant")
2171     public void test_toEpochSecond_UTC(LocalDateTime ldt, long expectedEpSec, int expectedNos) {
2172         ZonedDateTime dt = ldt.atZone(ZoneOffset.UTC);
2173         assertEquals(dt.toEpochSecond(), expectedEpSec);
2174     }
2175 
2176     @Test(dataProvider="toInstant")
2177     public void test_toEpochSecond_P0100(LocalDateTime ldt, long expectedEpSec, int expectedNos) {
2178         ZonedDateTime dt = ldt.atZone(ZONE_0100);
2179         assertEquals(dt.toEpochSecond(), expectedEpSec - 3600);
2180     }
2181 
2182     @Test(dataProvider="toInstant")
2183     public void test_toEpochSecond_M0100(LocalDateTime ldt, long expectedEpSec, int expectedNos) {
2184         ZonedDateTime dt = ldt.atZone(ZONE_M0100);
2185         assertEquals(dt.toEpochSecond(), expectedEpSec + 3600);
2186     }
2187 
2188     //-----------------------------------------------------------------------
2189     // compareTo()
2190     //-----------------------------------------------------------------------
2191     @Test
2192     public void test_compareTo_time1() {
2193         ZonedDateTime a = ZonedDateTime.of(2008, 6, 30, 11, 30, 39, 0, ZONE_0100);
2194         ZonedDateTime b = ZonedDateTime.of(2008, 6, 30, 11, 30, 41, 0, ZONE_0100);  // a is before b due to time
2195         assertEquals(a.compareTo(b) < 0, true);
2196         assertEquals(b.compareTo(a) > 0, true);
2197         assertEquals(a.compareTo(a) == 0, true);
2198         assertEquals(b.compareTo(b) == 0, true);
2199     }
2200 
2201     @Test
2202     public void test_compareTo_time2() {
2203         ZonedDateTime a = ZonedDateTime.of(2008, 6, 30, 11, 30, 40, 4, ZONE_0100);
2204         ZonedDateTime b = ZonedDateTime.of(2008, 6, 30, 11, 30, 40, 5, ZONE_0100);  // a is before b due to time
2205         assertEquals(a.compareTo(b) < 0, true);
2206         assertEquals(b.compareTo(a) > 0, true);
2207         assertEquals(a.compareTo(a) == 0, true);
2208         assertEquals(b.compareTo(b) == 0, true);
2209     }
2210 
2211     @Test
2212     public void test_compareTo_offset1() {
2213         ZonedDateTime a = ZonedDateTime.of(2008, 6, 30, 11, 30, 41, 0, ZONE_0200);
2214         ZonedDateTime b = ZonedDateTime.of(2008, 6, 30, 11, 30, 39, 0, ZONE_0100);  // a is before b due to offset
2215         assertEquals(a.compareTo(b) < 0, true);
2216         assertEquals(b.compareTo(a) > 0, true);
2217         assertEquals(a.compareTo(a) == 0, true);
2218         assertEquals(b.compareTo(b) == 0, true);
2219     }
2220 
2221     @Test
2222     public void test_compareTo_offset2() {
2223         ZonedDateTime a = ZonedDateTime.of(2008, 6, 30, 11, 30, 40, 5, ZoneId.of("UTC+01:01"));
2224         ZonedDateTime b = ZonedDateTime.of(2008, 6, 30, 11, 30, 40, 4, ZONE_0100);  // a is before b due to offset
2225         assertEquals(a.compareTo(b) < 0, true);
2226         assertEquals(b.compareTo(a) > 0, true);
2227         assertEquals(a.compareTo(a) == 0, true);
2228         assertEquals(b.compareTo(b) == 0, true);
2229     }
2230 
2231     @Test
2232     public void test_compareTo_both() {
2233         ZonedDateTime a = ZonedDateTime.of(2008, 6, 30, 11, 50, 0, 0, ZONE_0200);
2234         ZonedDateTime b = ZonedDateTime.of(2008, 6, 30, 11, 20, 0, 0, ZONE_0100);  // a is before b on instant scale
2235         assertEquals(a.compareTo(b) < 0, true);
2236         assertEquals(b.compareTo(a) > 0, true);
2237         assertEquals(a.compareTo(a) == 0, true);
2238         assertEquals(b.compareTo(b) == 0, true);
2239     }
2240 
2241     @Test
2242     public void test_compareTo_bothNanos() {
2243         ZonedDateTime a = ZonedDateTime.of(2008, 6, 30, 11, 20, 40, 5, ZONE_0200);
2244         ZonedDateTime b = ZonedDateTime.of(2008, 6, 30, 10, 20, 40, 6, ZONE_0100);  // a is before b on instant scale
2245         assertEquals(a.compareTo(b) < 0, true);
2246         assertEquals(b.compareTo(a) > 0, true);
2247         assertEquals(a.compareTo(a) == 0, true);
2248         assertEquals(b.compareTo(b) == 0, true);
2249     }
2250 
2251     @Test
2252     public void test_compareTo_hourDifference() {
2253         ZonedDateTime a = ZonedDateTime.of(2008, 6, 30, 10, 0, 0, 0, ZONE_0100);
2254         ZonedDateTime b = ZonedDateTime.of(2008, 6, 30, 11, 0, 0, 0, ZONE_0200);  // a is before b despite being same time-line time
2255         assertEquals(a.compareTo(b) < 0, true);
2256         assertEquals(b.compareTo(a) > 0, true);
2257         assertEquals(a.compareTo(a) == 0, true);
2258         assertEquals(b.compareTo(b) == 0, true);
2259     }
2260 
2261     @Test(expectedExceptions=NullPointerException.class)
2262     public void test_compareTo_null() {
2263         ZonedDateTime a = ZonedDateTime.of(2008, 6, 30, 23, 30, 59, 0, ZONE_0100);
2264         a.compareTo(null);
2265     }
2266 
2267     //-----------------------------------------------------------------------
2268     // isBefore()
2269     //-----------------------------------------------------------------------
2270     @DataProvider(name="IsBefore")
2271     Object[][] data_isBefore() {
2272         return new Object[][] {
2273             {11, 30, ZONE_0100, 11, 31, ZONE_0100, true}, // a is before b due to time
2274             {11, 30, ZONE_0200, 11, 30, ZONE_0100, true}, // a is before b due to offset
2275             {11, 30, ZONE_0200, 10, 30, ZONE_0100, false}, // a is equal b due to same instant
2276         };
2277     }
2278 
2279     @Test(dataProvider="IsBefore")
2280     public void test_isBefore(int hour1, int minute1, ZoneId zone1, int hour2, int minute2, ZoneId zone2, boolean expected) {
2281         ZonedDateTime a = ZonedDateTime.of(2008, 6, 30, hour1, minute1, 0, 0, zone1);
2282         ZonedDateTime b = ZonedDateTime.of(2008, 6, 30, hour2, minute2, 0, 0, zone2);
2283         assertEquals(a.isBefore(b), expected);
2284         assertEquals(b.isBefore(a), false);
2285         assertEquals(a.isBefore(a), false);
2286         assertEquals(b.isBefore(b), false);
2287     }
2288 
2289     @Test(expectedExceptions=NullPointerException.class)
2290     public void test_isBefore_null() {
2291         ZonedDateTime a = ZonedDateTime.of(2008, 6, 30, 23, 30, 59, 0, ZONE_0100);
2292         a.isBefore(null);
2293     }
2294 
2295     //-----------------------------------------------------------------------
2296     // isAfter()
2297     //-----------------------------------------------------------------------
2298     @DataProvider(name="IsAfter")
2299     Object[][] data_isAfter() {
2300         return new Object[][] {
2301             {11, 31, ZONE_0100, 11, 30, ZONE_0100, true}, // a is after b due to time
2302             {11, 30, ZONE_0100, 11, 30, ZONE_0200, true}, // a is after b due to offset
2303             {11, 30, ZONE_0200, 10, 30, ZONE_0100, false}, // a is equal b due to same instant
2304         };
2305     }
2306 
2307     @Test(dataProvider="IsAfter")
2308     public void test_isAfter(int hour1, int minute1, ZoneId zone1, int hour2, int minute2, ZoneId zone2, boolean expected) {
2309         ZonedDateTime a = ZonedDateTime.of(2008, 6, 30, hour1, minute1, 0, 0, zone1);
2310         ZonedDateTime b = ZonedDateTime.of(2008, 6, 30, hour2, minute2, 0, 0, zone2);
2311         assertEquals(a.isAfter(b), expected);
2312         assertEquals(b.isAfter(a), false);
2313         assertEquals(a.isAfter(a), false);
2314         assertEquals(b.isAfter(b), false);
2315     }
2316 
2317     @Test(expectedExceptions=NullPointerException.class)
2318     public void test_isAfter_null() {
2319         ZonedDateTime a = ZonedDateTime.of(2008, 6, 30, 23, 30, 59, 0, ZONE_0100);
2320         a.isAfter(null);
2321     }
2322 
2323     //-----------------------------------------------------------------------
2324     // equals() / hashCode()
2325     //-----------------------------------------------------------------------
2326     @Test(dataProvider="sampleTimes")
2327     public void test_equals_true(int y, int o, int d, int h, int m, int s, int n, ZoneId ignored) {
2328         ZonedDateTime a = ZonedDateTime.of(dateTime(y, o, d, h, m, s, n), ZONE_0100);
2329         ZonedDateTime b = ZonedDateTime.of(dateTime(y, o, d, h, m, s, n), ZONE_0100);
2330         assertEquals(a.equals(b), true);
2331         assertEquals(a.hashCode() == b.hashCode(), true);
2332     }
2333     @Test(dataProvider="sampleTimes")
2334     public void test_equals_false_year_differs(int y, int o, int d, int h, int m, int s, int n, ZoneId ignored) {
2335         ZonedDateTime a = ZonedDateTime.of(dateTime(y, o, d, h, m, s, n), ZONE_0100);
2336         ZonedDateTime b = ZonedDateTime.of(dateTime(y + 1, o, d, h, m, s, n), ZONE_0100);
2337         assertEquals(a.equals(b), false);
2338     }
2339     @Test(dataProvider="sampleTimes")
2340     public void test_equals_false_hour_differs(int y, int o, int d, int h, int m, int s, int n, ZoneId ignored) {
2341         h = (h == 23 ? 22 : h);
2342         ZonedDateTime a = ZonedDateTime.of(dateTime(y, o, d, h, m, s, n), ZONE_0100);
2343         ZonedDateTime b = ZonedDateTime.of(dateTime(y, o, d, h + 1, m, s, n), ZONE_0100);
2344         assertEquals(a.equals(b), false);
2345     }
2346     @Test(dataProvider="sampleTimes")
2347     public void test_equals_false_minute_differs(int y, int o, int d, int h, int m, int s, int n, ZoneId ignored) {
2348         m = (m == 59 ? 58 : m);
2349         ZonedDateTime a = ZonedDateTime.of(dateTime(y, o, d, h, m, s, n), ZONE_0100);
2350         ZonedDateTime b = ZonedDateTime.of(dateTime(y, o, d, h, m + 1, s, n), ZONE_0100);
2351         assertEquals(a.equals(b), false);
2352     }
2353     @Test(dataProvider="sampleTimes")
2354     public void test_equals_false_second_differs(int y, int o, int d, int h, int m, int s, int n, ZoneId ignored) {
2355         s = (s == 59 ? 58 : s);
2356         ZonedDateTime a = ZonedDateTime.of(dateTime(y, o, d, h, m, s, n), ZONE_0100);
2357         ZonedDateTime b = ZonedDateTime.of(dateTime(y, o, d, h, m, s + 1, n), ZONE_0100);
2358         assertEquals(a.equals(b), false);
2359     }
2360     @Test(dataProvider="sampleTimes")
2361     public void test_equals_false_nano_differs(int y, int o, int d, int h, int m, int s, int n, ZoneId ignored) {
2362         n = (n == 999999999 ? 999999998 : n);
2363         ZonedDateTime a = ZonedDateTime.of(dateTime(y, o, d, h, m, s, n), ZONE_0100);
2364         ZonedDateTime b = ZonedDateTime.of(dateTime(y, o, d, h, m, s, n + 1), ZONE_0100);
2365         assertEquals(a.equals(b), false);
2366     }
2367     @Test(dataProvider="sampleTimes")
2368     public void test_equals_false_offset_differs(int y, int o, int d, int h, int m, int s, int n, ZoneId ignored) {
2369         ZonedDateTime a = ZonedDateTime.of(dateTime(y, o, d, h, m, s, n), ZONE_0100);
2370         ZonedDateTime b = ZonedDateTime.of(dateTime(y, o, d, h, m, s, n), ZONE_0200);
2371         assertEquals(a.equals(b), false);
2372     }
2373 
2374     @Test
2375     public void test_equals_itself_true() {
2376         assertEquals(TEST_DATE_TIME.equals(TEST_DATE_TIME), true);
2377     }
2378 
2379     @Test
2380     public void test_equals_string_false() {
2381         assertEquals(TEST_DATE_TIME.equals("2007-07-15"), false);
2382     }
2383 
2384     //-----------------------------------------------------------------------
2385     // toString()
2386     //-----------------------------------------------------------------------
2387     @DataProvider(name="sampleToString")
2388     Object[][] provider_sampleToString() {
2389         return new Object[][] {
2390             {2008, 6, 30, 11, 30, 59, 0, "Z", "2008-06-30T11:30:59Z"},
2391             {2008, 6, 30, 11, 30, 59, 0, "+01:00", "2008-06-30T11:30:59+01:00"},
2392             {2008, 6, 30, 11, 30, 59, 999000000, "Z", "2008-06-30T11:30:59.999Z"},
2393             {2008, 6, 30, 11, 30, 59, 999000000, "+01:00", "2008-06-30T11:30:59.999+01:00"},
2394             {2008, 6, 30, 11, 30, 59, 999000, "Z", "2008-06-30T11:30:59.000999Z"},
2395             {2008, 6, 30, 11, 30, 59, 999000, "+01:00", "2008-06-30T11:30:59.000999+01:00"},
2396             {2008, 6, 30, 11, 30, 59, 999, "Z", "2008-06-30T11:30:59.000000999Z"},
2397             {2008, 6, 30, 11, 30, 59, 999, "+01:00", "2008-06-30T11:30:59.000000999+01:00"},
2398 
2399             {2008, 6, 30, 11, 30, 59, 999, "Europe/London", "2008-06-30T11:30:59.000000999+01:00[Europe/London]"},
2400             {2008, 6, 30, 11, 30, 59, 999, "Europe/Paris", "2008-06-30T11:30:59.000000999+02:00[Europe/Paris]"},
2401         };
2402     }
2403 
2404     @Test(dataProvider="sampleToString")
2405     public void test_toString(int y, int o, int d, int h, int m, int s, int n, String zoneId, String expected) {
2406         ZonedDateTime t = ZonedDateTime.of(dateTime(y, o, d, h, m, s, n), ZoneId.of(zoneId));
2407         String str = t.toString();
2408         assertEquals(str, expected);
2409     }
2410 
2411     //-------------------------------------------------------------------------
2412     private static LocalDateTime dateTime(
2413             int year, int month, int dayOfMonth,
2414             int hour, int minute) {
2415         return LocalDateTime.of(year, month, dayOfMonth, hour, minute);
2416     }
2417 
2418     private static LocalDateTime dateTime(
2419                     int year, int month, int dayOfMonth,
2420                     int hour, int minute, int second, int nanoOfSecond) {
2421                 return LocalDateTime.of(year, month, dayOfMonth, hour, minute, second, nanoOfSecond);
2422             }
2423 
2424     private static ZonedDateTime dateTime(
2425             int year, int month, int dayOfMonth,
2426             int hour, int minute, int second, int nanoOfSecond, ZoneOffset offset, ZoneId zoneId) {
2427         return ZonedDateTime.ofStrict(LocalDateTime.of(year, month, dayOfMonth, hour, minute, second, nanoOfSecond), offset, zoneId);
2428     }
2429 
2430 }