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