1/*
2 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/*
25 * This file is available under and governed by the GNU General Public
26 * License version 2 only, as published by the Free Software Foundation.
27 * However, the following notice accompanied the original version of this
28 * file:
29 *
30 * Copyright (c) 2007-2012, Stephen Colebourne & Michael Nascimento Santos
31 *
32 * All rights reserved.
33 *
34 * Redistribution and use in source and binary forms, with or without
35 * modification, are permitted provided that the following conditions are met:
36 *
37 *  * Redistributions of source code must retain the above copyright notice,
38 *    this list of conditions and the following disclaimer.
39 *
40 *  * Redistributions in binary form must reproduce the above copyright notice,
41 *    this list of conditions and the following disclaimer in the documentation
42 *    and/or other materials provided with the distribution.
43 *
44 *  * Neither the name of JSR-310 nor the names of its contributors
45 *    may be used to endorse or promote products derived from this software
46 *    without specific prior written permission.
47 *
48 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
49 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
50 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
51 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
52 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
53 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
54 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
55 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
56 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
57 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
58 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59 */
60package tck.java.time;
61
62import static java.time.temporal.ChronoUnit.DAYS;
63import static java.time.temporal.ChronoUnit.HALF_DAYS;
64import static java.time.temporal.ChronoUnit.HOURS;
65import static java.time.temporal.ChronoUnit.MICROS;
66import static java.time.temporal.ChronoUnit.MILLIS;
67import static java.time.temporal.ChronoUnit.MINUTES;
68import static java.time.temporal.ChronoUnit.NANOS;
69import static java.time.temporal.ChronoUnit.SECONDS;
70import static java.time.temporal.ChronoUnit.WEEKS;
71import static org.testng.Assert.assertEquals;
72import static org.testng.Assert.assertTrue;
73import static org.testng.Assert.fail;
74
75import java.io.ByteArrayOutputStream;
76import java.io.DataOutputStream;
77import java.time.DateTimeException;
78import java.time.Duration;
79import java.time.Instant;
80import java.time.LocalDate;
81import java.time.LocalDateTime;
82import java.time.LocalTime;
83import java.time.Period;
84import java.time.ZoneOffset;
85import java.time.ZonedDateTime;
86import java.time.format.DateTimeParseException;
87import java.time.temporal.ChronoUnit;
88import java.time.temporal.Temporal;
89import java.time.temporal.TemporalAmount;
90import java.time.temporal.TemporalUnit;
91import java.util.ArrayList;
92import java.util.Collections;
93import java.util.List;
94import java.util.Locale;
95
96import org.testng.annotations.DataProvider;
97import org.testng.annotations.Test;
98
99/**
100 * Test Duration.
101 */
102@Test
103public class TCKDuration extends AbstractTCKTest {
104
105    private static final long CYCLE_SECS = 146097L * 86400L;
106
107    //-----------------------------------------------------------------------
108    // constants
109    //-----------------------------------------------------------------------
110    @Test
111    public void test_zero() {
112        assertEquals(Duration.ZERO.getSeconds(), 0L);
113        assertEquals(Duration.ZERO.getNano(), 0);
114    }
115
116    //-----------------------------------------------------------------------
117    // ofSeconds(long)
118    //-----------------------------------------------------------------------
119    @Test
120    public void factory_seconds_long() {
121        for (long i = -2; i <= 2; i++) {
122            Duration t = Duration.ofSeconds(i);
123            assertEquals(t.getSeconds(), i);
124            assertEquals(t.getNano(), 0);
125        }
126    }
127
128    //-----------------------------------------------------------------------
129    // ofSeconds(long,long)
130    //-----------------------------------------------------------------------
131    @Test
132    public void factory_seconds_long_long() {
133        for (long i = -2; i <= 2; i++) {
134            for (int j = 0; j < 10; j++) {
135                Duration t = Duration.ofSeconds(i, j);
136                assertEquals(t.getSeconds(), i);
137                assertEquals(t.getNano(), j);
138            }
139            for (int j = -10; j < 0; j++) {
140                Duration t = Duration.ofSeconds(i, j);
141                assertEquals(t.getSeconds(), i - 1);
142                assertEquals(t.getNano(), j + 1000000000);
143            }
144            for (int j = 999999990; j < 1000000000; j++) {
145                Duration t = Duration.ofSeconds(i, j);
146                assertEquals(t.getSeconds(), i);
147                assertEquals(t.getNano(), j);
148            }
149        }
150    }
151
152    @Test
153    public void factory_seconds_long_long_nanosNegativeAdjusted() {
154        Duration test = Duration.ofSeconds(2L, -1);
155        assertEquals(test.getSeconds(), 1);
156        assertEquals(test.getNano(), 999999999);
157    }
158
159    @Test(expectedExceptions=ArithmeticException.class)
160    public void factory_seconds_long_long_tooBig() {
161        Duration.ofSeconds(Long.MAX_VALUE, 1000000000);
162    }
163
164    //-----------------------------------------------------------------------
165    // ofMillis(long)
166    //-----------------------------------------------------------------------
167    @DataProvider(name="MillisDurationNoNanos")
168    Object[][] provider_factory_millis_long() {
169        return new Object[][] {
170            {0, 0, 0},
171            {1, 0, 1000000},
172            {2, 0, 2000000},
173            {999, 0, 999000000},
174            {1000, 1, 0},
175            {1001, 1, 1000000},
176            {-1, -1, 999000000},
177            {-2, -1, 998000000},
178            {-999, -1, 1000000},
179            {-1000, -1, 0},
180            {-1001, -2, 999000000},
181        };
182    }
183
184    @Test(dataProvider="MillisDurationNoNanos")
185    public void factory_millis_long(long millis, long expectedSeconds, int expectedNanoOfSecond) {
186        Duration test = Duration.ofMillis(millis);
187        assertEquals(test.getSeconds(), expectedSeconds);
188        assertEquals(test.getNano(), expectedNanoOfSecond);
189    }
190
191    //-----------------------------------------------------------------------
192    // ofNanos(long)
193    //-----------------------------------------------------------------------
194    @Test
195    public void factory_nanos_nanos() {
196        Duration test = Duration.ofNanos(1);
197        assertEquals(test.getSeconds(), 0);
198        assertEquals(test.getNano(), 1);
199    }
200
201    @Test
202    public void factory_nanos_nanosSecs() {
203        Duration test = Duration.ofNanos(1000000002);
204        assertEquals(test.getSeconds(), 1);
205        assertEquals(test.getNano(), 2);
206    }
207
208    @Test
209    public void factory_nanos_negative() {
210        Duration test = Duration.ofNanos(-2000000001);
211        assertEquals(test.getSeconds(), -3);
212        assertEquals(test.getNano(), 999999999);
213    }
214
215    @Test
216    public void factory_nanos_max() {
217        Duration test = Duration.ofNanos(Long.MAX_VALUE);
218        assertEquals(test.getSeconds(), Long.MAX_VALUE / 1000000000);
219        assertEquals(test.getNano(), Long.MAX_VALUE % 1000000000);
220    }
221
222    @Test
223    public void factory_nanos_min() {
224        Duration test = Duration.ofNanos(Long.MIN_VALUE);
225        assertEquals(test.getSeconds(), Long.MIN_VALUE / 1000000000 - 1);
226        assertEquals(test.getNano(), Long.MIN_VALUE % 1000000000 + 1000000000);
227    }
228
229    //-----------------------------------------------------------------------
230    // ofMinutes()
231    //-----------------------------------------------------------------------
232    @Test
233    public void factory_minutes() {
234        Duration test = Duration.ofMinutes(2);
235        assertEquals(test.getSeconds(), 120);
236        assertEquals(test.getNano(), 0);
237    }
238
239    @Test
240    public void factory_minutes_max() {
241        Duration test = Duration.ofMinutes(Long.MAX_VALUE / 60);
242        assertEquals(test.getSeconds(), (Long.MAX_VALUE / 60) * 60);
243        assertEquals(test.getNano(), 0);
244    }
245
246    @Test
247    public void factory_minutes_min() {
248        Duration test = Duration.ofMinutes(Long.MIN_VALUE / 60);
249        assertEquals(test.getSeconds(), (Long.MIN_VALUE / 60) * 60);
250        assertEquals(test.getNano(), 0);
251    }
252
253    @Test(expectedExceptions=ArithmeticException.class)
254    public void factory_minutes_tooBig() {
255        Duration.ofMinutes(Long.MAX_VALUE / 60 + 1);
256    }
257
258    @Test(expectedExceptions=ArithmeticException.class)
259    public void factory_minutes_tooSmall() {
260        Duration.ofMinutes(Long.MIN_VALUE / 60 - 1);
261    }
262
263    //-----------------------------------------------------------------------
264    // ofHours()
265    //-----------------------------------------------------------------------
266    @Test
267    public void factory_hours() {
268        Duration test = Duration.ofHours(2);
269        assertEquals(test.getSeconds(), 2 * 3600);
270        assertEquals(test.getNano(), 0);
271    }
272
273    @Test
274    public void factory_hours_max() {
275        Duration test = Duration.ofHours(Long.MAX_VALUE / 3600);
276        assertEquals(test.getSeconds(), (Long.MAX_VALUE / 3600) * 3600);
277        assertEquals(test.getNano(), 0);
278    }
279
280    @Test
281    public void factory_hours_min() {
282        Duration test = Duration.ofHours(Long.MIN_VALUE / 3600);
283        assertEquals(test.getSeconds(), (Long.MIN_VALUE / 3600) * 3600);
284        assertEquals(test.getNano(), 0);
285    }
286
287    @Test(expectedExceptions=ArithmeticException.class)
288    public void factory_hours_tooBig() {
289        Duration.ofHours(Long.MAX_VALUE / 3600 + 1);
290    }
291
292    @Test(expectedExceptions=ArithmeticException.class)
293    public void factory_hours_tooSmall() {
294        Duration.ofHours(Long.MIN_VALUE / 3600 - 1);
295    }
296
297    //-----------------------------------------------------------------------
298    // ofDays()
299    //-----------------------------------------------------------------------
300    @Test
301    public void factory_days() {
302        Duration test = Duration.ofDays(2);
303        assertEquals(test.getSeconds(), 2 * 86400);
304        assertEquals(test.getNano(), 0);
305    }
306
307    @Test
308    public void factory_days_max() {
309        Duration test = Duration.ofDays(Long.MAX_VALUE / 86400);
310        assertEquals(test.getSeconds(), (Long.MAX_VALUE / 86400) * 86400);
311        assertEquals(test.getNano(), 0);
312    }
313
314    @Test
315    public void factory_days_min() {
316        Duration test = Duration.ofDays(Long.MIN_VALUE / 86400);
317        assertEquals(test.getSeconds(), (Long.MIN_VALUE / 86400) * 86400);
318        assertEquals(test.getNano(), 0);
319    }
320
321    @Test(expectedExceptions=ArithmeticException.class)
322    public void factory_days_tooBig() {
323        Duration.ofDays(Long.MAX_VALUE / 86400 + 1);
324    }
325
326    @Test(expectedExceptions=ArithmeticException.class)
327    public void factory_days_tooSmall() {
328        Duration.ofDays(Long.MIN_VALUE / 86400 - 1);
329    }
330
331    //-----------------------------------------------------------------------
332    // of(long,TemporalUnit)
333    //-----------------------------------------------------------------------
334    @DataProvider(name="OfTemporalUnit")
335    Object[][] provider_factory_of_longTemporalUnit() {
336        return new Object[][] {
337            {0, NANOS, 0, 0},
338            {0, MICROS, 0, 0},
339            {0, MILLIS, 0, 0},
340            {0, SECONDS, 0, 0},
341            {0, MINUTES, 0, 0},
342            {0, HOURS, 0, 0},
343            {0, HALF_DAYS, 0, 0},
344            {0, DAYS, 0, 0},
345            {1, NANOS, 0, 1},
346            {1, MICROS, 0, 1000},
347            {1, MILLIS, 0, 1000000},
348            {1, SECONDS, 1, 0},
349            {1, MINUTES, 60, 0},
350            {1, HOURS, 3600, 0},
351            {1, HALF_DAYS, 43200, 0},
352            {1, DAYS, 86400, 0},
353            {3, NANOS, 0, 3},
354            {3, MICROS, 0, 3000},
355            {3, MILLIS, 0, 3000000},
356            {3, SECONDS, 3, 0},
357            {3, MINUTES, 3 * 60, 0},
358            {3, HOURS, 3 * 3600, 0},
359            {3, HALF_DAYS, 3 * 43200, 0},
360            {3, DAYS, 3 * 86400, 0},
361            {-1, NANOS, -1, 999999999},
362            {-1, MICROS, -1, 999999000},
363            {-1, MILLIS, -1, 999000000},
364            {-1, SECONDS, -1, 0},
365            {-1, MINUTES, -60, 0},
366            {-1, HOURS, -3600, 0},
367            {-1, HALF_DAYS, -43200, 0},
368            {-1, DAYS, -86400, 0},
369            {-3, NANOS, -1, 999999997},
370            {-3, MICROS, -1, 999997000},
371            {-3, MILLIS, -1, 997000000},
372            {-3, SECONDS, -3, 0},
373            {-3, MINUTES, -3 * 60, 0},
374            {-3, HOURS, -3 * 3600, 0},
375            {-3, HALF_DAYS, -3 * 43200, 0},
376            {-3, DAYS, -3 * 86400, 0},
377            {Long.MAX_VALUE, NANOS, Long.MAX_VALUE / 1000000000, (int) (Long.MAX_VALUE % 1000000000)},
378            {Long.MIN_VALUE, NANOS, Long.MIN_VALUE / 1000000000 - 1, (int) (Long.MIN_VALUE % 1000000000 + 1000000000)},
379            {Long.MAX_VALUE, MICROS, Long.MAX_VALUE / 1000000, (int) ((Long.MAX_VALUE % 1000000) * 1000)},
380            {Long.MIN_VALUE, MICROS, Long.MIN_VALUE / 1000000 - 1, (int) ((Long.MIN_VALUE % 1000000 + 1000000) * 1000)},
381            {Long.MAX_VALUE, MILLIS, Long.MAX_VALUE / 1000, (int) ((Long.MAX_VALUE % 1000) * 1000000)},
382            {Long.MIN_VALUE, MILLIS, Long.MIN_VALUE / 1000 - 1, (int) ((Long.MIN_VALUE % 1000 + 1000) * 1000000)},
383            {Long.MAX_VALUE, SECONDS, Long.MAX_VALUE, 0},
384            {Long.MIN_VALUE, SECONDS, Long.MIN_VALUE, 0},
385            {Long.MAX_VALUE / 60, MINUTES, (Long.MAX_VALUE / 60) * 60, 0},
386            {Long.MIN_VALUE / 60, MINUTES, (Long.MIN_VALUE / 60) * 60, 0},
387            {Long.MAX_VALUE / 3600, HOURS, (Long.MAX_VALUE / 3600) * 3600, 0},
388            {Long.MIN_VALUE / 3600, HOURS, (Long.MIN_VALUE / 3600) * 3600, 0},
389            {Long.MAX_VALUE / 43200, HALF_DAYS, (Long.MAX_VALUE / 43200) * 43200, 0},
390            {Long.MIN_VALUE / 43200, HALF_DAYS, (Long.MIN_VALUE / 43200) * 43200, 0},
391        };
392    }
393
394    @Test(dataProvider="OfTemporalUnit")
395    public void factory_of_longTemporalUnit(long amount, TemporalUnit unit, long expectedSeconds, int expectedNanoOfSecond) {
396        Duration t = Duration.of(amount, unit);
397        assertEquals(t.getSeconds(), expectedSeconds);
398        assertEquals(t.getNano(), expectedNanoOfSecond);
399    }
400
401    @DataProvider(name="OfTemporalUnitOutOfRange")
402    Object[][] provider_factory_of_longTemporalUnit_outOfRange() {
403        return new Object[][] {
404            {Long.MAX_VALUE / 60 + 1, MINUTES},
405            {Long.MIN_VALUE / 60 - 1, MINUTES},
406            {Long.MAX_VALUE / 3600 + 1, HOURS},
407            {Long.MIN_VALUE / 3600 - 1, HOURS},
408            {Long.MAX_VALUE / 43200 + 1, HALF_DAYS},
409            {Long.MIN_VALUE / 43200 - 1, HALF_DAYS},
410        };
411    }
412
413    @Test(dataProvider="OfTemporalUnitOutOfRange", expectedExceptions=ArithmeticException.class)
414    public void factory_of_longTemporalUnit_outOfRange(long amount, TemporalUnit unit) {
415        Duration.of(amount, unit);
416    }
417
418    @Test(expectedExceptions=DateTimeException.class)
419    public void factory_of_longTemporalUnit_estimatedUnit() {
420        Duration.of(2, WEEKS);
421    }
422
423    @Test(expectedExceptions=NullPointerException.class)
424    public void factory_of_longTemporalUnit_null() {
425        Duration.of(1, (TemporalUnit) null);
426    }
427
428    //-----------------------------------------------------------------------
429    // from(TemporalAmount)
430    //-----------------------------------------------------------------------
431    @Test
432    public void factory_from_TemporalAmount_Duration() {
433        TemporalAmount amount = Duration.ofHours(3);
434        assertEquals(Duration.from(amount), Duration.ofHours(3));
435    }
436
437    @Test
438    public void factory_from_TemporalAmount_DaysNanos() {
439        TemporalAmount amount = new TemporalAmount() {
440            @Override
441            public long get(TemporalUnit unit) {
442                if (unit == DAYS) {
443                    return 23;
444                } else {
445                    return 45;
446                }
447            }
448            @Override
449            public List<TemporalUnit> getUnits() {
450                List<TemporalUnit> list = new ArrayList<>();
451                list.add(DAYS);
452                list.add(NANOS);
453                return list;
454            }
455            @Override
456            public Temporal addTo(Temporal temporal) {
457                throw new UnsupportedOperationException();
458            }
459            @Override
460            public Temporal subtractFrom(Temporal temporal) {
461                throw new UnsupportedOperationException();
462            }
463        };
464        Duration t = Duration.from(amount);
465        assertEquals(t.getSeconds(), 23 * 86400);
466        assertEquals(t.getNano(), 45);
467    }
468
469    @Test(expectedExceptions = ArithmeticException.class)
470    public void factory_from_TemporalAmount_Minutes_tooBig() {
471        TemporalAmount amount = new TemporalAmount() {
472            @Override
473            public long get(TemporalUnit unit) {
474                return (Long.MAX_VALUE / 60) + 2;
475            }
476            @Override
477            public List<TemporalUnit> getUnits() {
478                return Collections.<TemporalUnit>singletonList(MINUTES);
479            }
480            @Override
481            public Temporal addTo(Temporal temporal) {
482                throw new UnsupportedOperationException();
483            }
484            @Override
485            public Temporal subtractFrom(Temporal temporal) {
486                throw new UnsupportedOperationException();
487            }
488        };
489        Duration.from(amount);
490    }
491
492    @Test(expectedExceptions = DateTimeException.class)
493    public void factory_from_TemporalAmount_Period() {
494        Duration.from(Period.ZERO);
495    }
496
497    @Test(expectedExceptions = NullPointerException.class)
498    public void factory_from_TemporalAmount_null() {
499        Duration.from(null);
500    }
501
502    //-----------------------------------------------------------------------
503    // parse(String)
504    //-----------------------------------------------------------------------
505    @DataProvider(name="parseSuccess")
506    Object[][] data_parseSuccess() {
507        return new Object[][] {
508                {"PT0S", 0, 0},
509                {"PT1S", 1, 0},
510                {"PT12S", 12, 0},
511                {"PT123456789S", 123456789, 0},
512                {"PT" + Long.MAX_VALUE + "S", Long.MAX_VALUE, 0},
513
514                {"PT+1S", 1, 0},
515                {"PT+12S", 12, 0},
516                {"PT+123456789S", 123456789, 0},
517                {"PT+" + Long.MAX_VALUE + "S", Long.MAX_VALUE, 0},
518
519                {"PT-1S", -1, 0},
520                {"PT-12S", -12, 0},
521                {"PT-123456789S", -123456789, 0},
522                {"PT" + Long.MIN_VALUE + "S", Long.MIN_VALUE, 0},
523
524                {"PT1.1S", 1, 100000000},
525                {"PT1.12S", 1, 120000000},
526                {"PT1.123S", 1, 123000000},
527                {"PT1.1234S", 1, 123400000},
528                {"PT1.12345S", 1, 123450000},
529                {"PT1.123456S", 1, 123456000},
530                {"PT1.1234567S", 1, 123456700},
531                {"PT1.12345678S", 1, 123456780},
532                {"PT1.123456789S", 1, 123456789},
533
534                {"PT-1.1S", -2, 1000000000 - 100000000},
535                {"PT-1.12S", -2, 1000000000 - 120000000},
536                {"PT-1.123S", -2, 1000000000 - 123000000},
537                {"PT-1.1234S", -2, 1000000000 - 123400000},
538                {"PT-1.12345S", -2, 1000000000 - 123450000},
539                {"PT-1.123456S", -2, 1000000000 - 123456000},
540                {"PT-1.1234567S", -2, 1000000000 - 123456700},
541                {"PT-1.12345678S", -2, 1000000000 - 123456780},
542                {"PT-1.123456789S", -2, 1000000000 - 123456789},
543
544                {"PT" + Long.MAX_VALUE + ".123456789S", Long.MAX_VALUE, 123456789},
545                {"PT" + Long.MIN_VALUE + ".000000000S", Long.MIN_VALUE, 0},
546
547                {"PT01S", 1, 0},
548                {"PT001S", 1, 0},
549                {"PT000S", 0, 0},
550                {"PT+01S", 1, 0},
551                {"PT-01S", -1, 0},
552
553                {"PT1.S", 1, 0},
554                {"PT+1.S", 1, 0},
555                {"PT-1.S", -1, 0},
556
557                {"P0D", 0, 0},
558                {"P0DT0H", 0, 0},
559                {"P0DT0M", 0, 0},
560                {"P0DT0S", 0, 0},
561                {"P0DT0H0S", 0, 0},
562                {"P0DT0M0S", 0, 0},
563                {"P0DT0H0M0S", 0, 0},
564
565                {"P1D", 86400, 0},
566                {"P1DT0H", 86400, 0},
567                {"P1DT0M", 86400, 0},
568                {"P1DT0S", 86400, 0},
569                {"P1DT0H0S", 86400, 0},
570                {"P1DT0M0S", 86400, 0},
571                {"P1DT0H0M0S", 86400, 0},
572
573                {"P3D", 86400 * 3, 0},
574                {"P3DT2H", 86400 * 3 + 3600 * 2, 0},
575                {"P3DT2M", 86400 * 3 + 60 * 2, 0},
576                {"P3DT2S", 86400 * 3 + 2, 0},
577                {"P3DT2H1S", 86400 * 3 + 3600 * 2 + 1, 0},
578                {"P3DT2M1S", 86400 * 3 + 60 * 2 + 1, 0},
579                {"P3DT2H1M1S", 86400 * 3 + 3600 * 2 + 60 + 1, 0},
580
581                {"P-3D", -86400 * 3, 0},
582                {"P-3DT2H", -86400 * 3 + 3600 * 2, 0},
583                {"P-3DT2M", -86400 * 3 + 60 * 2, 0},
584                {"P-3DT2S", -86400 * 3 + 2, 0},
585                {"P-3DT2H1S", -86400 * 3 + 3600 * 2 + 1, 0},
586                {"P-3DT2M1S", -86400 * 3 + 60 * 2 + 1, 0},
587                {"P-3DT2H1M1S", -86400 * 3 + 3600 * 2 + 60 + 1, 0},
588
589                {"P-3DT-2H", -86400 * 3 - 3600 * 2, 0},
590                {"P-3DT-2M", -86400 * 3 - 60 * 2, 0},
591                {"P-3DT-2S", -86400 * 3 - 2, 0},
592                {"P-3DT-2H1S", -86400 * 3 - 3600 * 2 + 1, 0},
593                {"P-3DT-2M1S", -86400 * 3 - 60 * 2 + 1, 0},
594                {"P-3DT-2H1M1S", -86400 * 3 - 3600 * 2 + 60 + 1, 0},
595
596                {"PT0H", 0, 0},
597                {"PT0H0M", 0, 0},
598                {"PT0H0S", 0, 0},
599                {"PT0H0M0S", 0, 0},
600
601                {"PT1H", 3600, 0},
602                {"PT3H", 3600 * 3, 0},
603                {"PT-1H", -3600, 0},
604                {"PT-3H", -3600 * 3, 0},
605
606                {"PT2H5M", 3600 * 2 + 60 * 5, 0},
607                {"PT2H5S", 3600 * 2 + 5, 0},
608                {"PT2H5M8S", 3600 * 2 + 60 * 5 + 8, 0},
609                {"PT-2H5M", -3600 * 2 + 60 * 5, 0},
610                {"PT-2H5S", -3600 * 2 + 5, 0},
611                {"PT-2H5M8S", -3600 * 2 + 60 * 5 + 8, 0},
612                {"PT-2H-5M", -3600 * 2 - 60 * 5, 0},
613                {"PT-2H-5S", -3600 * 2 - 5, 0},
614                {"PT-2H-5M8S", -3600 * 2 - 60 * 5 + 8, 0},
615                {"PT-2H-5M-8S", -3600 * 2 - 60 * 5 - 8, 0},
616
617                {"PT0M", 0, 0},
618                {"PT1M", 60, 0},
619                {"PT3M", 60 * 3, 0},
620                {"PT-1M", -60, 0},
621                {"PT-3M", -60 * 3, 0},
622                {"P0DT3M", 60 * 3, 0},
623                {"P0DT-3M", -60 * 3, 0},
624        };
625    }
626
627    @Test(dataProvider="parseSuccess")
628    public void factory_parse(String text, long expectedSeconds, int expectedNanoOfSecond) {
629        Duration test = Duration.parse(text);
630        assertEquals(test.getSeconds(), expectedSeconds);
631        assertEquals(test.getNano(), expectedNanoOfSecond);
632    }
633
634    @Test(dataProvider="parseSuccess")
635    public void factory_parse_plus(String text, long expectedSeconds, int expectedNanoOfSecond) {
636        Duration test = Duration.parse("+" + text);
637        assertEquals(test.getSeconds(), expectedSeconds);
638        assertEquals(test.getNano(), expectedNanoOfSecond);
639    }
640
641    @Test(dataProvider="parseSuccess")
642    public void factory_parse_minus(String text, long expectedSeconds, int expectedNanoOfSecond) {
643        Duration test;
644        try {
645            test = Duration.parse("-" + text);
646        } catch (DateTimeParseException ex) {
647            assertEquals(expectedSeconds == Long.MIN_VALUE, true);
648            return;
649        }
650        // not inside try/catch or it breaks test
651        assertEquals(test, Duration.ofSeconds(expectedSeconds, expectedNanoOfSecond).negated());
652    }
653
654    @Test(dataProvider="parseSuccess")
655    public void factory_parse_comma(String text, long expectedSeconds, int expectedNanoOfSecond) {
656        text = text.replace('.', ',');
657        Duration test = Duration.parse(text);
658        assertEquals(test.getSeconds(), expectedSeconds);
659        assertEquals(test.getNano(), expectedNanoOfSecond);
660    }
661
662    @Test(dataProvider="parseSuccess")
663    public void factory_parse_lowerCase(String text, long expectedSeconds, int expectedNanoOfSecond) {
664        Duration test = Duration.parse(text.toLowerCase(Locale.ENGLISH));
665        assertEquals(test.getSeconds(), expectedSeconds);
666        assertEquals(test.getNano(), expectedNanoOfSecond);
667    }
668
669    @DataProvider(name="parseFailure")
670    Object[][] data_parseFailure() {
671        return new Object[][] {
672                {""},
673                {"ABCDEF"},
674                {" PT0S"},
675                {"PT0S "},
676
677                {"PTS"},
678                {"AT0S"},
679                {"PA0S"},
680                {"PT0A"},
681
682                {"P0Y"},
683                {"P1Y"},
684                {"P-2Y"},
685                {"P0M"},
686                {"P1M"},
687                {"P-2M"},
688                {"P3Y2D"},
689                {"P3M2D"},
690                {"P3W"},
691                {"P-3W"},
692                {"P2YT30S"},
693                {"P2MT30S"},
694
695                {"P1DT"},
696
697                {"PT+S"},
698                {"PT-S"},
699                {"PT.S"},
700                {"PTAS"},
701
702                {"PT-.S"},
703                {"PT+.S"},
704
705                {"PT1ABC2S"},
706                {"PT1.1ABC2S"},
707
708                {"PT123456789123456789123456789S"},
709                {"PT0.1234567891S"},
710
711                {"PT2.-3"},
712                {"PT-2.-3"},
713                {"PT2.+3"},
714                {"PT-2.+3"},
715        };
716    }
717
718    @Test(dataProvider="parseFailure", expectedExceptions=DateTimeParseException.class)
719    public void factory_parseFailures(String text) {
720        Duration.parse(text);
721    }
722
723    @Test(dataProvider="parseFailure", expectedExceptions=DateTimeParseException.class)
724    public void factory_parseFailures_comma(String text) {
725        text = text.replace('.', ',');
726        Duration.parse(text);
727    }
728
729    @Test(expectedExceptions=DateTimeParseException.class)
730    public void factory_parse_tooBig() {
731        Duration.parse("PT" + Long.MAX_VALUE + "1S");
732    }
733
734    @Test(expectedExceptions=DateTimeParseException.class)
735    public void factory_parse_tooBig_decimal() {
736        Duration.parse("PT" + Long.MAX_VALUE + "1.1S");
737    }
738
739    @Test(expectedExceptions=DateTimeParseException.class)
740    public void factory_parse_tooSmall() {
741        Duration.parse("PT" + Long.MIN_VALUE + "1S");
742    }
743
744    @Test(expectedExceptions=DateTimeParseException.class)
745    public void factory_parse_tooSmall_decimal() {
746        Duration.parse("PT" + Long.MIN_VALUE + ".1S");
747    }
748
749    @Test(expectedExceptions=NullPointerException.class)
750    public void factory_parse_nullText() {
751        Duration.parse(null);
752    }
753
754    //-----------------------------------------------------------------------
755    // between()
756    //-----------------------------------------------------------------------
757    @DataProvider(name="durationBetweenInstant")
758    Object[][] data_durationBetweenInstant() {
759        return new Object[][] {
760                {0, 0, 0, 0, 0, 0},
761                {3, 0, 7, 0, 4, 0},
762                {7, 0, 3, 0, -4, 0},
763
764                {3, 20, 7, 50, 4, 30},
765                {3, 80, 7, 50, 3, 999999970},
766                {3, 80, 7, 79, 3, 999999999},
767                {3, 80, 7, 80, 4, 0},
768                {3, 80, 7, 81, 4, 1},
769        };
770    }
771
772    @Test(dataProvider="durationBetweenInstant")
773    public void factory_between_TemporalTemporal_Instant(long secs1, int nanos1, long secs2, int nanos2, long expectedSeconds, int expectedNanoOfSecond) {
774        Instant start = Instant.ofEpochSecond(secs1, nanos1);
775        Instant end = Instant.ofEpochSecond(secs2, nanos2);
776        Duration t = Duration.between(start, end);
777        assertEquals(t.getSeconds(), expectedSeconds);
778        assertEquals(t.getNano(), expectedNanoOfSecond);
779    }
780
781    @Test(dataProvider="durationBetweenInstant")
782    public void factory_between_TemporalTemporal_Instant_negated(long secs1, int nanos1, long secs2, int nanos2, long expectedSeconds, int expectedNanoOfSecond) {
783        Instant start = Instant.ofEpochSecond(secs1, nanos1);
784        Instant end = Instant.ofEpochSecond(secs2, nanos2);
785        assertEquals(Duration.between(end, start), Duration.between(start, end).negated());
786    }
787
788    @DataProvider(name="durationBetweenLocalTime")
789    Object[][] data_durationBetweenLocalTime() {
790        return new Object[][] {
791                {LocalTime.of(11, 0, 30), LocalTime.of(11, 0, 45), 15L, 0},
792                {LocalTime.of(11, 0, 30), LocalTime.of(11, 0, 25), -5L, 0},
793        };
794    }
795
796    @Test(dataProvider="durationBetweenLocalTime")
797    public void factory_between_TemporalTemporal_LT(LocalTime start, LocalTime end, long expectedSeconds, int expectedNanoOfSecond) {
798        Duration t = Duration.between(start, end);
799        assertEquals(t.getSeconds(), expectedSeconds);
800        assertEquals(t.getNano(), expectedNanoOfSecond);
801    }
802
803    @Test(dataProvider="durationBetweenLocalTime")
804    public void factory_between_TemporalTemporal_LT_negated(LocalTime start, LocalTime end, long expectedSeconds, int expectedNanoOfSecond) {
805        assertEquals(Duration.between(end, start), Duration.between(start, end).negated());
806    }
807
808    @DataProvider(name="durationBetweenLocalDateTime")
809    Object[][] data_durationBetweenLocalDateTime() {
810        return new Object[][] {
811                {LocalDateTime.of(2013, 3, 24, 0, 44, 31, 565_000_000), LocalDateTime.of(2013, 3, 24, 0, 44, 30, 65_000_000), -2L, 500_000_000},
812                {LocalDateTime.of(2013, 3, 24, 0, 44, 31, 565_000_000), LocalDateTime.of(2013, 3, 24, 0, 44, 31, 65_000_000), -1L, 500_000_000},
813                {LocalDateTime.of(2013, 3, 24, 0, 44, 31, 565_000_000), LocalDateTime.of(2013, 3, 24, 0, 44, 32, 65_000_000), 0L, 500_000_000},
814                {LocalDateTime.of(2013, 3, 24, 0, 44, 31, 565_000_000), LocalDateTime.of(2013, 3, 24, 0, 44, 33, 65_000_000), 1L, 500_000_000},
815                {LocalDateTime.of(2013, 3, 24, 0, 44, 31, 565_000_000), LocalDateTime.of(2013, 3, 24, 0, 44, 34, 65_000_000), 2L, 500_000_000},
816
817                {LocalDateTime.of(2013, 3, 24, 0, 44, 31, 65_000_000), LocalDateTime.of(2013, 3, 24, 0, 44, 30, 565_000_000), -1L, 500_000_000},
818                {LocalDateTime.of(2013, 3, 24, 0, 44, 31, 65_000_000), LocalDateTime.of(2013, 3, 24, 0, 44, 31, 565_000_000), 0L, 500_000_000},
819                {LocalDateTime.of(2013, 3, 24, 0, 44, 31, 65_000_000), LocalDateTime.of(2013, 3, 24, 0, 44, 32, 565_000_000), 1L, 500_000_000},
820                {LocalDateTime.of(2013, 3, 24, 0, 44, 31, 65_000_000), LocalDateTime.of(2013, 3, 24, 0, 44, 33, 565_000_000), 2L, 500_000_000},
821                {LocalDateTime.of(2013, 3, 24, 0, 44, 31, 65_000_000), LocalDateTime.of(2013, 3, 24, 0, 44, 34, 565_000_000), 3L, 500_000_000},
822
823                {LocalDateTime.of(2013, 3, 24, 0, 44, 31, 65_000_000), LocalDateTime.of(2013, 3, 24, 0, 44, 30, 65_000_000), -1L, 0},
824                {LocalDateTime.of(2013, 3, 24, 0, 44, 31, 65_000_000), LocalDateTime.of(2013, 3, 24, 0, 44, 31, 65_000_000), 0L, 0},
825                {LocalDateTime.of(2013, 3, 24, 0, 44, 31, 65_000_000), LocalDateTime.of(2013, 3, 24, 0, 44, 32, 65_000_000), 1L, 0},
826                {LocalDateTime.of(2013, 3, 24, 0, 44, 31, 65_000_000), LocalDateTime.of(2013, 3, 24, 0, 44, 33, 65_000_000), 2L, 0},
827                {LocalDateTime.of(2013, 3, 24, 0, 44, 31, 65_000_000), LocalDateTime.of(2013, 3, 24, 0, 44, 34, 65_000_000), 3L, 0},
828
829                {LocalDateTime.of(2013, 3, 24, 0, 44, 31, 65_000_000), LocalDateTime.of(2813, 3, 24, 0, 44, 30, 565_000_000), 2 * CYCLE_SECS - 1L, 500_000_000},
830                {LocalDateTime.of(2013, 3, 24, 0, 44, 31, 65_000_000), LocalDateTime.of(2813, 3, 24, 0, 44, 31, 565_000_000), 2 * CYCLE_SECS + 0L, 500_000_000},
831                {LocalDateTime.of(2013, 3, 24, 0, 44, 31, 65_000_000), LocalDateTime.of(2813, 3, 24, 0, 44, 32, 565_000_000), 2 * CYCLE_SECS + 1L, 500_000_000},
832        };
833    }
834
835    @Test(dataProvider="durationBetweenLocalDateTime")
836    public void factory_between_TemporalTemporal_LDT(LocalDateTime start, LocalDateTime end, long expectedSeconds, int expectedNanoOfSecond) {
837        Duration t = Duration.between(start, end);
838        assertEquals(t.getSeconds(), expectedSeconds);
839        assertEquals(t.getNano(), expectedNanoOfSecond);
840    }
841
842    @Test(dataProvider="durationBetweenLocalDateTime")
843    public void factory_between_TemporalTemporal_LDT_negated(LocalDateTime start, LocalDateTime end, long expectedSeconds, int expectedNanoOfSecond) {
844        assertEquals(Duration.between(end, start), Duration.between(start, end).negated());
845    }
846
847    @Test
848    public void factory_between_TemporalTemporal_mixedTypes() {
849        Instant start = Instant.ofEpochSecond(1);
850        ZonedDateTime end = Instant.ofEpochSecond(4).atZone(ZoneOffset.UTC);
851        assertEquals(Duration.between(start, end), Duration.ofSeconds(3));
852    }
853
854    @Test(expectedExceptions=DateTimeException.class)
855    public void factory_between_TemporalTemporal_invalidMixedTypes() {
856        Instant start = Instant.ofEpochSecond(1);
857        LocalDate end = LocalDate.of(2010, 6, 20);
858        Duration.between(start, end);
859    }
860
861    @Test(expectedExceptions=NullPointerException.class)
862    public void factory_between__TemporalTemporal_startNull() {
863        Instant end = Instant.ofEpochSecond(1);
864        Duration.between(null, end);
865    }
866
867    @Test(expectedExceptions=NullPointerException.class)
868    public void factory_between__TemporalTemporal_endNull() {
869        Instant start = Instant.ofEpochSecond(1);
870        Duration.between(start, null);
871    }
872
873    //-----------------------------------------------------------------------
874    // isZero(), isPositive(), isPositiveOrZero(), isNegative(), isNegativeOrZero()
875    //-----------------------------------------------------------------------
876    @Test
877    public void test_isZero() {
878        assertEquals(Duration.ofNanos(0).isZero(), true);
879        assertEquals(Duration.ofSeconds(0).isZero(), true);
880        assertEquals(Duration.ofNanos(1).isZero(), false);
881        assertEquals(Duration.ofSeconds(1).isZero(), false);
882        assertEquals(Duration.ofSeconds(1, 1).isZero(), false);
883        assertEquals(Duration.ofNanos(-1).isZero(), false);
884        assertEquals(Duration.ofSeconds(-1).isZero(), false);
885        assertEquals(Duration.ofSeconds(-1, -1).isZero(), false);
886    }
887
888    @Test
889    public void test_isNegative() {
890        assertEquals(Duration.ofNanos(0).isNegative(), false);
891        assertEquals(Duration.ofSeconds(0).isNegative(), false);
892        assertEquals(Duration.ofNanos(1).isNegative(), false);
893        assertEquals(Duration.ofSeconds(1).isNegative(), false);
894        assertEquals(Duration.ofSeconds(1, 1).isNegative(), false);
895        assertEquals(Duration.ofNanos(-1).isNegative(), true);
896        assertEquals(Duration.ofSeconds(-1).isNegative(), true);
897        assertEquals(Duration.ofSeconds(-1, -1).isNegative(), true);
898    }
899
900    //-----------------------------------------------------------------------
901    // plus()
902    //-----------------------------------------------------------------------
903    @DataProvider(name="Plus")
904    Object[][] provider_plus() {
905        return new Object[][] {
906            {Long.MIN_VALUE, 0, Long.MAX_VALUE, 0, -1, 0},
907
908            {-4, 666666667, -4, 666666667, -7, 333333334},
909            {-4, 666666667, -3,         0, -7, 666666667},
910            {-4, 666666667, -2,         0, -6, 666666667},
911            {-4, 666666667, -1,         0, -5, 666666667},
912            {-4, 666666667, -1, 333333334, -4,         1},
913            {-4, 666666667, -1, 666666667, -4, 333333334},
914            {-4, 666666667, -1, 999999999, -4, 666666666},
915            {-4, 666666667,  0,         0, -4, 666666667},
916            {-4, 666666667,  0,         1, -4, 666666668},
917            {-4, 666666667,  0, 333333333, -3,         0},
918            {-4, 666666667,  0, 666666666, -3, 333333333},
919            {-4, 666666667,  1,         0, -3, 666666667},
920            {-4, 666666667,  2,         0, -2, 666666667},
921            {-4, 666666667,  3,         0, -1, 666666667},
922            {-4, 666666667,  3, 333333333,  0,         0},
923
924            {-3, 0, -4, 666666667, -7, 666666667},
925            {-3, 0, -3,         0, -6,         0},
926            {-3, 0, -2,         0, -5,         0},
927            {-3, 0, -1,         0, -4,         0},
928            {-3, 0, -1, 333333334, -4, 333333334},
929            {-3, 0, -1, 666666667, -4, 666666667},
930            {-3, 0, -1, 999999999, -4, 999999999},
931            {-3, 0,  0,         0, -3,         0},
932            {-3, 0,  0,         1, -3,         1},
933            {-3, 0,  0, 333333333, -3, 333333333},
934            {-3, 0,  0, 666666666, -3, 666666666},
935            {-3, 0,  1,         0, -2,         0},
936            {-3, 0,  2,         0, -1,         0},
937            {-3, 0,  3,         0,  0,         0},
938            {-3, 0,  3, 333333333,  0, 333333333},
939
940            {-2, 0, -4, 666666667, -6, 666666667},
941            {-2, 0, -3,         0, -5,         0},
942            {-2, 0, -2,         0, -4,         0},
943            {-2, 0, -1,         0, -3,         0},
944            {-2, 0, -1, 333333334, -3, 333333334},
945            {-2, 0, -1, 666666667, -3, 666666667},
946            {-2, 0, -1, 999999999, -3, 999999999},
947            {-2, 0,  0,         0, -2,         0},
948            {-2, 0,  0,         1, -2,         1},
949            {-2, 0,  0, 333333333, -2, 333333333},
950            {-2, 0,  0, 666666666, -2, 666666666},
951            {-2, 0,  1,         0, -1,         0},
952            {-2, 0,  2,         0,  0,         0},
953            {-2, 0,  3,         0,  1,         0},
954            {-2, 0,  3, 333333333,  1, 333333333},
955
956            {-1, 0, -4, 666666667, -5, 666666667},
957            {-1, 0, -3,         0, -4,         0},
958            {-1, 0, -2,         0, -3,         0},
959            {-1, 0, -1,         0, -2,         0},
960            {-1, 0, -1, 333333334, -2, 333333334},
961            {-1, 0, -1, 666666667, -2, 666666667},
962            {-1, 0, -1, 999999999, -2, 999999999},
963            {-1, 0,  0,         0, -1,         0},
964            {-1, 0,  0,         1, -1,         1},
965            {-1, 0,  0, 333333333, -1, 333333333},
966            {-1, 0,  0, 666666666, -1, 666666666},
967            {-1, 0,  1,         0,  0,         0},
968            {-1, 0,  2,         0,  1,         0},
969            {-1, 0,  3,         0,  2,         0},
970            {-1, 0,  3, 333333333,  2, 333333333},
971
972            {-1, 666666667, -4, 666666667, -4, 333333334},
973            {-1, 666666667, -3,         0, -4, 666666667},
974            {-1, 666666667, -2,         0, -3, 666666667},
975            {-1, 666666667, -1,         0, -2, 666666667},
976            {-1, 666666667, -1, 333333334, -1,         1},
977            {-1, 666666667, -1, 666666667, -1, 333333334},
978            {-1, 666666667, -1, 999999999, -1, 666666666},
979            {-1, 666666667,  0,         0, -1, 666666667},
980            {-1, 666666667,  0,         1, -1, 666666668},
981            {-1, 666666667,  0, 333333333,  0,         0},
982            {-1, 666666667,  0, 666666666,  0, 333333333},
983            {-1, 666666667,  1,         0,  0, 666666667},
984            {-1, 666666667,  2,         0,  1, 666666667},
985            {-1, 666666667,  3,         0,  2, 666666667},
986            {-1, 666666667,  3, 333333333,  3,         0},
987
988            {0, 0, -4, 666666667, -4, 666666667},
989            {0, 0, -3,         0, -3,         0},
990            {0, 0, -2,         0, -2,         0},
991            {0, 0, -1,         0, -1,         0},
992            {0, 0, -1, 333333334, -1, 333333334},
993            {0, 0, -1, 666666667, -1, 666666667},
994            {0, 0, -1, 999999999, -1, 999999999},
995            {0, 0,  0,         0,  0,         0},
996            {0, 0,  0,         1,  0,         1},
997            {0, 0,  0, 333333333,  0, 333333333},
998            {0, 0,  0, 666666666,  0, 666666666},
999            {0, 0,  1,         0,  1,         0},
1000            {0, 0,  2,         0,  2,         0},
1001            {0, 0,  3,         0,  3,         0},
1002            {0, 0,  3, 333333333,  3, 333333333},
1003
1004            {0, 333333333, -4, 666666667, -3,         0},
1005            {0, 333333333, -3,         0, -3, 333333333},
1006            {0, 333333333, -2,         0, -2, 333333333},
1007            {0, 333333333, -1,         0, -1, 333333333},
1008            {0, 333333333, -1, 333333334, -1, 666666667},
1009            {0, 333333333, -1, 666666667,  0,         0},
1010            {0, 333333333, -1, 999999999,  0, 333333332},
1011            {0, 333333333,  0,         0,  0, 333333333},
1012            {0, 333333333,  0,         1,  0, 333333334},
1013            {0, 333333333,  0, 333333333,  0, 666666666},
1014            {0, 333333333,  0, 666666666,  0, 999999999},
1015            {0, 333333333,  1,         0,  1, 333333333},
1016            {0, 333333333,  2,         0,  2, 333333333},
1017            {0, 333333333,  3,         0,  3, 333333333},
1018            {0, 333333333,  3, 333333333,  3, 666666666},
1019
1020            {1, 0, -4, 666666667, -3, 666666667},
1021            {1, 0, -3,         0, -2,         0},
1022            {1, 0, -2,         0, -1,         0},
1023            {1, 0, -1,         0,  0,         0},
1024            {1, 0, -1, 333333334,  0, 333333334},
1025            {1, 0, -1, 666666667,  0, 666666667},
1026            {1, 0, -1, 999999999,  0, 999999999},
1027            {1, 0,  0,         0,  1,         0},
1028            {1, 0,  0,         1,  1,         1},
1029            {1, 0,  0, 333333333,  1, 333333333},
1030            {1, 0,  0, 666666666,  1, 666666666},
1031            {1, 0,  1,         0,  2,         0},
1032            {1, 0,  2,         0,  3,         0},
1033            {1, 0,  3,         0,  4,         0},
1034            {1, 0,  3, 333333333,  4, 333333333},
1035
1036            {2, 0, -4, 666666667, -2, 666666667},
1037            {2, 0, -3,         0, -1,         0},
1038            {2, 0, -2,         0,  0,         0},
1039            {2, 0, -1,         0,  1,         0},
1040            {2, 0, -1, 333333334,  1, 333333334},
1041            {2, 0, -1, 666666667,  1, 666666667},
1042            {2, 0, -1, 999999999,  1, 999999999},
1043            {2, 0,  0,         0,  2,         0},
1044            {2, 0,  0,         1,  2,         1},
1045            {2, 0,  0, 333333333,  2, 333333333},
1046            {2, 0,  0, 666666666,  2, 666666666},
1047            {2, 0,  1,         0,  3,         0},
1048            {2, 0,  2,         0,  4,         0},
1049            {2, 0,  3,         0,  5,         0},
1050            {2, 0,  3, 333333333,  5, 333333333},
1051
1052            {3, 0, -4, 666666667, -1, 666666667},
1053            {3, 0, -3,         0,  0,         0},
1054            {3, 0, -2,         0,  1,         0},
1055            {3, 0, -1,         0,  2,         0},
1056            {3, 0, -1, 333333334,  2, 333333334},
1057            {3, 0, -1, 666666667,  2, 666666667},
1058            {3, 0, -1, 999999999,  2, 999999999},
1059            {3, 0,  0,         0,  3,         0},
1060            {3, 0,  0,         1,  3,         1},
1061            {3, 0,  0, 333333333,  3, 333333333},
1062            {3, 0,  0, 666666666,  3, 666666666},
1063            {3, 0,  1,         0,  4,         0},
1064            {3, 0,  2,         0,  5,         0},
1065            {3, 0,  3,         0,  6,         0},
1066            {3, 0,  3, 333333333,  6, 333333333},
1067
1068            {3, 333333333, -4, 666666667,  0,         0},
1069            {3, 333333333, -3,         0,  0, 333333333},
1070            {3, 333333333, -2,         0,  1, 333333333},
1071            {3, 333333333, -1,         0,  2, 333333333},
1072            {3, 333333333, -1, 333333334,  2, 666666667},
1073            {3, 333333333, -1, 666666667,  3,         0},
1074            {3, 333333333, -1, 999999999,  3, 333333332},
1075            {3, 333333333,  0,         0,  3, 333333333},
1076            {3, 333333333,  0,         1,  3, 333333334},
1077            {3, 333333333,  0, 333333333,  3, 666666666},
1078            {3, 333333333,  0, 666666666,  3, 999999999},
1079            {3, 333333333,  1,         0,  4, 333333333},
1080            {3, 333333333,  2,         0,  5, 333333333},
1081            {3, 333333333,  3,         0,  6, 333333333},
1082            {3, 333333333,  3, 333333333,  6, 666666666},
1083
1084            {Long.MAX_VALUE, 0, Long.MIN_VALUE, 0, -1, 0},
1085       };
1086    }
1087
1088    @Test(dataProvider="Plus")
1089    public void plus(long seconds, int nanos, long otherSeconds, int otherNanos, long expectedSeconds, int expectedNanoOfSecond) {
1090       Duration t = Duration.ofSeconds(seconds, nanos).plus(Duration.ofSeconds(otherSeconds, otherNanos));
1091       assertEquals(t.getSeconds(), expectedSeconds);
1092       assertEquals(t.getNano(), expectedNanoOfSecond);
1093    }
1094
1095    @Test(expectedExceptions=ArithmeticException.class)
1096    public void plusOverflowTooBig() {
1097       Duration t = Duration.ofSeconds(Long.MAX_VALUE, 999999999);
1098       t.plus(Duration.ofSeconds(0, 1));
1099    }
1100
1101    @Test(expectedExceptions=ArithmeticException.class)
1102    public void plusOverflowTooSmall() {
1103       Duration t = Duration.ofSeconds(Long.MIN_VALUE);
1104       t.plus(Duration.ofSeconds(-1, 999999999));
1105    }
1106
1107    //-----------------------------------------------------------------------
1108    @Test
1109    public void plus_longTemporalUnit_seconds() {
1110        Duration t = Duration.ofSeconds(1);
1111        t = t.plus(1, SECONDS);
1112        assertEquals(2, t.getSeconds());
1113        assertEquals(0, t.getNano());
1114     }
1115
1116    @Test
1117    public void plus_longTemporalUnit_millis() {
1118        Duration t = Duration.ofSeconds(1);
1119        t = t.plus(1, MILLIS);
1120        assertEquals(1, t.getSeconds());
1121        assertEquals(1000000, t.getNano());
1122     }
1123
1124    @Test
1125    public void plus_longTemporalUnit_micros() {
1126        Duration t = Duration.ofSeconds(1);
1127        t = t.plus(1, MICROS);
1128        assertEquals(1, t.getSeconds());
1129        assertEquals(1000, t.getNano());
1130     }
1131
1132    @Test
1133    public void plus_longTemporalUnit_nanos() {
1134        Duration t = Duration.ofSeconds(1);
1135        t = t.plus(1, NANOS);
1136        assertEquals(1, t.getSeconds());
1137        assertEquals(1, t.getNano());
1138     }
1139
1140    @Test(expectedExceptions=NullPointerException.class)
1141    public void plus_longTemporalUnit_null() {
1142       Duration t = Duration.ofSeconds(1);
1143       t.plus(1, (TemporalUnit) null);
1144    }
1145
1146    //-----------------------------------------------------------------------
1147    @DataProvider(name="PlusDays")
1148    Object[][] provider_plusDays_long() {
1149        return new Object[][] {
1150            {0, 0, 0},
1151            {0, 1, 1},
1152            {0, -1, -1},
1153            {Long.MAX_VALUE/3600/24, 0, Long.MAX_VALUE/3600/24},
1154            {Long.MIN_VALUE/3600/24, 0, Long.MIN_VALUE/3600/24},
1155            {1, 0, 1},
1156            {1, 1, 2},
1157            {1, -1, 0},
1158            {1, Long.MIN_VALUE/3600/24, Long.MIN_VALUE/3600/24 + 1},
1159            {1, 0, 1},
1160            {1, 1, 2},
1161            {1, -1, 0},
1162            {-1, 0, -1},
1163            {-1, 1, 0},
1164            {-1, -1, -2},
1165            {-1, Long.MAX_VALUE/3600/24, Long.MAX_VALUE/3600/24 - 1},
1166        };
1167    }
1168
1169    @Test(dataProvider="PlusDays")
1170    public void plusDays_long(long days, long amount, long expectedDays) {
1171        Duration t = Duration.ofDays(days);
1172        t = t.plusDays(amount);
1173        assertEquals(t.toDays(), expectedDays);
1174    }
1175
1176    @Test(expectedExceptions = {ArithmeticException.class})
1177    public void plusDays_long_overflowTooBig() {
1178        Duration t = Duration.ofDays(1);
1179        t.plusDays(Long.MAX_VALUE/3600/24);
1180    }
1181
1182    @Test(expectedExceptions = {ArithmeticException.class})
1183    public void plusDays_long_overflowTooSmall() {
1184        Duration t = Duration.ofDays(-1);
1185        t.plusDays(Long.MIN_VALUE/3600/24);
1186    }
1187
1188    //-----------------------------------------------------------------------
1189    @DataProvider(name="PlusHours")
1190    Object[][] provider_plusHours_long() {
1191        return new Object[][] {
1192            {0, 0, 0},
1193            {0, 1, 1},
1194            {0, -1, -1},
1195            {Long.MAX_VALUE/3600, 0, Long.MAX_VALUE/3600},
1196            {Long.MIN_VALUE/3600, 0, Long.MIN_VALUE/3600},
1197            {1, 0, 1},
1198            {1, 1, 2},
1199            {1, -1, 0},
1200            {1, Long.MIN_VALUE/3600, Long.MIN_VALUE/3600 + 1},
1201            {1, 0, 1},
1202            {1, 1, 2},
1203            {1, -1, 0},
1204            {-1, 0, -1},
1205            {-1, 1, 0},
1206            {-1, -1, -2},
1207            {-1, Long.MAX_VALUE/3600, Long.MAX_VALUE/3600 - 1},
1208        };
1209    }
1210
1211    @Test(dataProvider="PlusHours")
1212    public void plusHours_long(long hours, long amount, long expectedHours) {
1213        Duration t = Duration.ofHours(hours);
1214        t = t.plusHours(amount);
1215        assertEquals(t.toHours(), expectedHours);
1216    }
1217
1218    @Test(expectedExceptions = {ArithmeticException.class})
1219    public void plusHours_long_overflowTooBig() {
1220        Duration t = Duration.ofHours(1);
1221        t.plusHours(Long.MAX_VALUE/3600);
1222    }
1223
1224    @Test(expectedExceptions = {ArithmeticException.class})
1225    public void plusHours_long_overflowTooSmall() {
1226        Duration t = Duration.ofHours(-1);
1227        t.plusHours(Long.MIN_VALUE/3600);
1228    }
1229
1230    //-----------------------------------------------------------------------
1231    @DataProvider(name="PlusMinutes")
1232    Object[][] provider_plusMinutes_long() {
1233        return new Object[][] {
1234            {0, 0, 0},
1235            {0, 1, 1},
1236            {0, -1, -1},
1237            {Long.MAX_VALUE/60, 0, Long.MAX_VALUE/60},
1238            {Long.MIN_VALUE/60, 0, Long.MIN_VALUE/60},
1239            {1, 0, 1},
1240            {1, 1, 2},
1241            {1, -1, 0},
1242            {1, Long.MIN_VALUE/60, Long.MIN_VALUE/60 + 1},
1243            {1, 0, 1},
1244            {1, 1, 2},
1245            {1, -1, 0},
1246            {-1, 0, -1},
1247            {-1, 1, 0},
1248            {-1, -1, -2},
1249            {-1, Long.MAX_VALUE/60, Long.MAX_VALUE/60 - 1},
1250        };
1251    }
1252
1253    @Test(dataProvider="PlusMinutes")
1254    public void plusMinutes_long(long minutes, long amount, long expectedMinutes) {
1255        Duration t = Duration.ofMinutes(minutes);
1256        t = t.plusMinutes(amount);
1257        assertEquals(t.toMinutes(), expectedMinutes);
1258    }
1259
1260    @Test(expectedExceptions = {ArithmeticException.class})
1261    public void plusMinutes_long_overflowTooBig() {
1262        Duration t = Duration.ofMinutes(1);
1263        t.plusMinutes(Long.MAX_VALUE/60);
1264    }
1265
1266    @Test(expectedExceptions = {ArithmeticException.class})
1267    public void plusMinutes_long_overflowTooSmall() {
1268        Duration t = Duration.ofMinutes(-1);
1269        t.plusMinutes(Long.MIN_VALUE/60);
1270    }
1271
1272    //-----------------------------------------------------------------------
1273    @DataProvider(name="PlusSeconds")
1274    Object[][] provider_plusSeconds_long() {
1275        return new Object[][] {
1276            {0, 0, 0, 0, 0},
1277            {0, 0, 1, 1, 0},
1278            {0, 0, -1, -1, 0},
1279            {0, 0, Long.MAX_VALUE, Long.MAX_VALUE, 0},
1280            {0, 0, Long.MIN_VALUE, Long.MIN_VALUE, 0},
1281            {1, 0, 0, 1, 0},
1282            {1, 0, 1, 2, 0},
1283            {1, 0, -1, 0, 0},
1284            {1, 0, Long.MAX_VALUE - 1, Long.MAX_VALUE, 0},
1285            {1, 0, Long.MIN_VALUE, Long.MIN_VALUE + 1, 0},
1286            {1, 1, 0, 1, 1},
1287            {1, 1, 1, 2, 1},
1288            {1, 1, -1, 0, 1},
1289            {1, 1, Long.MAX_VALUE - 1, Long.MAX_VALUE, 1},
1290            {1, 1, Long.MIN_VALUE, Long.MIN_VALUE + 1, 1},
1291            {-1, 1, 0, -1, 1},
1292            {-1, 1, 1, 0, 1},
1293            {-1, 1, -1, -2, 1},
1294            {-1, 1, Long.MAX_VALUE, Long.MAX_VALUE - 1, 1},
1295            {-1, 1, Long.MIN_VALUE + 1, Long.MIN_VALUE, 1},
1296        };
1297    }
1298
1299    @Test(dataProvider="PlusSeconds")
1300    public void plusSeconds_long(long seconds, int nanos, long amount, long expectedSeconds, int expectedNanoOfSecond) {
1301        Duration t = Duration.ofSeconds(seconds, nanos);
1302        t = t.plusSeconds(amount);
1303        assertEquals(t.getSeconds(), expectedSeconds);
1304        assertEquals(t.getNano(), expectedNanoOfSecond);
1305    }
1306
1307    @Test(expectedExceptions = {ArithmeticException.class})
1308    public void plusSeconds_long_overflowTooBig() {
1309        Duration t = Duration.ofSeconds(1, 0);
1310        t.plusSeconds(Long.MAX_VALUE);
1311    }
1312
1313    @Test(expectedExceptions = {ArithmeticException.class})
1314    public void plusSeconds_long_overflowTooSmall() {
1315        Duration t = Duration.ofSeconds(-1, 0);
1316        t.plusSeconds(Long.MIN_VALUE);
1317    }
1318
1319    //-----------------------------------------------------------------------
1320    @DataProvider(name="PlusMillis")
1321    Object[][] provider_plusMillis_long() {
1322        return new Object[][] {
1323            {0, 0, 0,       0, 0},
1324            {0, 0, 1,       0, 1000000},
1325            {0, 0, 999,     0, 999000000},
1326            {0, 0, 1000,    1, 0},
1327            {0, 0, 1001,    1, 1000000},
1328            {0, 0, 1999,    1, 999000000},
1329            {0, 0, 2000,    2, 0},
1330            {0, 0, -1,      -1, 999000000},
1331            {0, 0, -999,    -1, 1000000},
1332            {0, 0, -1000,   -1, 0},
1333            {0, 0, -1001,   -2, 999000000},
1334            {0, 0, -1999,   -2, 1000000},
1335
1336            {0, 1, 0,       0, 1},
1337            {0, 1, 1,       0, 1000001},
1338            {0, 1, 998,     0, 998000001},
1339            {0, 1, 999,     0, 999000001},
1340            {0, 1, 1000,    1, 1},
1341            {0, 1, 1998,    1, 998000001},
1342            {0, 1, 1999,    1, 999000001},
1343            {0, 1, 2000,    2, 1},
1344            {0, 1, -1,      -1, 999000001},
1345            {0, 1, -2,      -1, 998000001},
1346            {0, 1, -1000,   -1, 1},
1347            {0, 1, -1001,   -2, 999000001},
1348
1349            {0, 1000000, 0,       0, 1000000},
1350            {0, 1000000, 1,       0, 2000000},
1351            {0, 1000000, 998,     0, 999000000},
1352            {0, 1000000, 999,     1, 0},
1353            {0, 1000000, 1000,    1, 1000000},
1354            {0, 1000000, 1998,    1, 999000000},
1355            {0, 1000000, 1999,    2, 0},
1356            {0, 1000000, 2000,    2, 1000000},
1357            {0, 1000000, -1,      0, 0},
1358            {0, 1000000, -2,      -1, 999000000},
1359            {0, 1000000, -999,    -1, 2000000},
1360            {0, 1000000, -1000,   -1, 1000000},
1361            {0, 1000000, -1001,   -1, 0},
1362            {0, 1000000, -1002,   -2, 999000000},
1363
1364            {0, 999999999, 0,     0, 999999999},
1365            {0, 999999999, 1,     1, 999999},
1366            {0, 999999999, 999,   1, 998999999},
1367            {0, 999999999, 1000,  1, 999999999},
1368            {0, 999999999, 1001,  2, 999999},
1369            {0, 999999999, -1,    0, 998999999},
1370            {0, 999999999, -1000, -1, 999999999},
1371            {0, 999999999, -1001, -1, 998999999},
1372        };
1373    }
1374
1375    @Test(dataProvider="PlusMillis")
1376    public void plusMillis_long(long seconds, int nanos, long amount, long expectedSeconds, int expectedNanoOfSecond) {
1377        Duration t = Duration.ofSeconds(seconds, nanos);
1378        t = t.plusMillis(amount);
1379        assertEquals(t.getSeconds(), expectedSeconds);
1380        assertEquals(t.getNano(), expectedNanoOfSecond);
1381    }
1382    @Test(dataProvider="PlusMillis")
1383    public void plusMillis_long_oneMore(long seconds, int nanos, long amount, long expectedSeconds, int expectedNanoOfSecond) {
1384        Duration t = Duration.ofSeconds(seconds + 1, nanos);
1385        t = t.plusMillis(amount);
1386        assertEquals(t.getSeconds(), expectedSeconds + 1);
1387        assertEquals(t.getNano(), expectedNanoOfSecond);
1388    }
1389    @Test(dataProvider="PlusMillis")
1390    public void plusMillis_long_minusOneLess(long seconds, int nanos, long amount, long expectedSeconds, int expectedNanoOfSecond) {
1391        Duration t = Duration.ofSeconds(seconds - 1, nanos);
1392        t = t.plusMillis(amount);
1393        assertEquals(t.getSeconds(), expectedSeconds - 1);
1394        assertEquals(t.getNano(), expectedNanoOfSecond);
1395    }
1396
1397    @Test
1398    public void plusMillis_long_max() {
1399        Duration t = Duration.ofSeconds(Long.MAX_VALUE, 998999999);
1400        t = t.plusMillis(1);
1401        assertEquals(t.getSeconds(), Long.MAX_VALUE);
1402        assertEquals(t.getNano(), 999999999);
1403    }
1404
1405    @Test(expectedExceptions = {ArithmeticException.class})
1406    public void plusMillis_long_overflowTooBig() {
1407        Duration t = Duration.ofSeconds(Long.MAX_VALUE, 999000000);
1408        t.plusMillis(1);
1409    }
1410
1411    @Test
1412    public void plusMillis_long_min() {
1413        Duration t = Duration.ofSeconds(Long.MIN_VALUE, 1000000);
1414        t = t.plusMillis(-1);
1415        assertEquals(t.getSeconds(), Long.MIN_VALUE);
1416        assertEquals(t.getNano(), 0);
1417    }
1418
1419    @Test(expectedExceptions = {ArithmeticException.class})
1420    public void plusMillis_long_overflowTooSmall() {
1421        Duration t = Duration.ofSeconds(Long.MIN_VALUE, 0);
1422        t.plusMillis(-1);
1423    }
1424
1425    //-----------------------------------------------------------------------
1426    @DataProvider(name="PlusNanos")
1427    Object[][] provider_plusNanos_long() {
1428        return new Object[][] {
1429            {0, 0, 0,           0, 0},
1430            {0, 0, 1,           0, 1},
1431            {0, 0, 999999999,   0, 999999999},
1432            {0, 0, 1000000000,  1, 0},
1433            {0, 0, 1000000001,  1, 1},
1434            {0, 0, 1999999999,  1, 999999999},
1435            {0, 0, 2000000000,  2, 0},
1436            {0, 0, -1,          -1, 999999999},
1437            {0, 0, -999999999,  -1, 1},
1438            {0, 0, -1000000000, -1, 0},
1439            {0, 0, -1000000001, -2, 999999999},
1440            {0, 0, -1999999999, -2, 1},
1441
1442            {1, 0, 0,           1, 0},
1443            {1, 0, 1,           1, 1},
1444            {1, 0, 999999999,   1, 999999999},
1445            {1, 0, 1000000000,  2, 0},
1446            {1, 0, 1000000001,  2, 1},
1447            {1, 0, 1999999999,  2, 999999999},
1448            {1, 0, 2000000000,  3, 0},
1449            {1, 0, -1,          0, 999999999},
1450            {1, 0, -999999999,  0, 1},
1451            {1, 0, -1000000000, 0, 0},
1452            {1, 0, -1000000001, -1, 999999999},
1453            {1, 0, -1999999999, -1, 1},
1454
1455            {-1, 0, 0,           -1, 0},
1456            {-1, 0, 1,           -1, 1},
1457            {-1, 0, 999999999,   -1, 999999999},
1458            {-1, 0, 1000000000,  0, 0},
1459            {-1, 0, 1000000001,  0, 1},
1460            {-1, 0, 1999999999,  0, 999999999},
1461            {-1, 0, 2000000000,  1, 0},
1462            {-1, 0, -1,          -2, 999999999},
1463            {-1, 0, -999999999,  -2, 1},
1464            {-1, 0, -1000000000, -2, 0},
1465            {-1, 0, -1000000001, -3, 999999999},
1466            {-1, 0, -1999999999, -3, 1},
1467
1468            {1, 1, 0,           1, 1},
1469            {1, 1, 1,           1, 2},
1470            {1, 1, 999999998,   1, 999999999},
1471            {1, 1, 999999999,   2, 0},
1472            {1, 1, 1000000000,  2, 1},
1473            {1, 1, 1999999998,  2, 999999999},
1474            {1, 1, 1999999999,  3, 0},
1475            {1, 1, 2000000000,  3, 1},
1476            {1, 1, -1,          1, 0},
1477            {1, 1, -2,          0, 999999999},
1478            {1, 1, -1000000000, 0, 1},
1479            {1, 1, -1000000001, 0, 0},
1480            {1, 1, -1000000002, -1, 999999999},
1481            {1, 1, -2000000000, -1, 1},
1482
1483            {1, 999999999, 0,           1, 999999999},
1484            {1, 999999999, 1,           2, 0},
1485            {1, 999999999, 999999999,   2, 999999998},
1486            {1, 999999999, 1000000000,  2, 999999999},
1487            {1, 999999999, 1000000001,  3, 0},
1488            {1, 999999999, -1,          1, 999999998},
1489            {1, 999999999, -1000000000, 0, 999999999},
1490            {1, 999999999, -1000000001, 0, 999999998},
1491            {1, 999999999, -1999999999, 0, 0},
1492            {1, 999999999, -2000000000, -1, 999999999},
1493
1494            {Long.MAX_VALUE, 0, 999999999, Long.MAX_VALUE, 999999999},
1495            {Long.MAX_VALUE - 1, 0, 1999999999, Long.MAX_VALUE, 999999999},
1496            {Long.MIN_VALUE, 1, -1, Long.MIN_VALUE, 0},
1497            {Long.MIN_VALUE + 1, 1, -1000000001, Long.MIN_VALUE, 0},
1498        };
1499    }
1500
1501    @Test(dataProvider="PlusNanos")
1502    public void plusNanos_long(long seconds, int nanos, long amount, long expectedSeconds, int expectedNanoOfSecond) {
1503        Duration t = Duration.ofSeconds(seconds, nanos);
1504        t = t.plusNanos(amount);
1505        assertEquals(t.getSeconds(), expectedSeconds);
1506        assertEquals(t.getNano(), expectedNanoOfSecond);
1507    }
1508
1509    @Test(expectedExceptions = {ArithmeticException.class})
1510    public void plusNanos_long_overflowTooBig() {
1511        Duration t = Duration.ofSeconds(Long.MAX_VALUE, 999999999);
1512        t.plusNanos(1);
1513    }
1514
1515    @Test(expectedExceptions = {ArithmeticException.class})
1516    public void plusNanos_long_overflowTooSmall() {
1517        Duration t = Duration.ofSeconds(Long.MIN_VALUE, 0);
1518        t.plusNanos(-1);
1519    }
1520
1521    //-----------------------------------------------------------------------
1522    @DataProvider(name="Minus")
1523    Object[][] provider_minus() {
1524        return new Object[][] {
1525            {Long.MIN_VALUE, 0, Long.MIN_VALUE + 1, 0, -1, 0},
1526
1527            {-4, 666666667, -4, 666666667,  0,         0},
1528            {-4, 666666667, -3,         0, -1, 666666667},
1529            {-4, 666666667, -2,         0, -2, 666666667},
1530            {-4, 666666667, -1,         0, -3, 666666667},
1531            {-4, 666666667, -1, 333333334, -3, 333333333},
1532            {-4, 666666667, -1, 666666667, -3,         0},
1533            {-4, 666666667, -1, 999999999, -4, 666666668},
1534            {-4, 666666667,  0,         0, -4, 666666667},
1535            {-4, 666666667,  0,         1, -4, 666666666},
1536            {-4, 666666667,  0, 333333333, -4, 333333334},
1537            {-4, 666666667,  0, 666666666, -4,         1},
1538            {-4, 666666667,  1,         0, -5, 666666667},
1539            {-4, 666666667,  2,         0, -6, 666666667},
1540            {-4, 666666667,  3,         0, -7, 666666667},
1541            {-4, 666666667,  3, 333333333, -7, 333333334},
1542
1543            {-3, 0, -4, 666666667,  0, 333333333},
1544            {-3, 0, -3,         0,  0,         0},
1545            {-3, 0, -2,         0, -1,         0},
1546            {-3, 0, -1,         0, -2,         0},
1547            {-3, 0, -1, 333333334, -3, 666666666},
1548            {-3, 0, -1, 666666667, -3, 333333333},
1549            {-3, 0, -1, 999999999, -3,         1},
1550            {-3, 0,  0,         0, -3,         0},
1551            {-3, 0,  0,         1, -4, 999999999},
1552            {-3, 0,  0, 333333333, -4, 666666667},
1553            {-3, 0,  0, 666666666, -4, 333333334},
1554            {-3, 0,  1,         0, -4,         0},
1555            {-3, 0,  2,         0, -5,         0},
1556            {-3, 0,  3,         0, -6,         0},
1557            {-3, 0,  3, 333333333, -7, 666666667},
1558
1559            {-2, 0, -4, 666666667,  1, 333333333},
1560            {-2, 0, -3,         0,  1,         0},
1561            {-2, 0, -2,         0,  0,         0},
1562            {-2, 0, -1,         0, -1,         0},
1563            {-2, 0, -1, 333333334, -2, 666666666},
1564            {-2, 0, -1, 666666667, -2, 333333333},
1565            {-2, 0, -1, 999999999, -2,         1},
1566            {-2, 0,  0,         0, -2,         0},
1567            {-2, 0,  0,         1, -3, 999999999},
1568            {-2, 0,  0, 333333333, -3, 666666667},
1569            {-2, 0,  0, 666666666, -3, 333333334},
1570            {-2, 0,  1,         0, -3,         0},
1571            {-2, 0,  2,         0, -4,         0},
1572            {-2, 0,  3,         0, -5,         0},
1573            {-2, 0,  3, 333333333, -6, 666666667},
1574
1575            {-1, 0, -4, 666666667,  2, 333333333},
1576            {-1, 0, -3,         0,  2,         0},
1577            {-1, 0, -2,         0,  1,         0},
1578            {-1, 0, -1,         0,  0,         0},
1579            {-1, 0, -1, 333333334, -1, 666666666},
1580            {-1, 0, -1, 666666667, -1, 333333333},
1581            {-1, 0, -1, 999999999, -1,         1},
1582            {-1, 0,  0,         0, -1,         0},
1583            {-1, 0,  0,         1, -2, 999999999},
1584            {-1, 0,  0, 333333333, -2, 666666667},
1585            {-1, 0,  0, 666666666, -2, 333333334},
1586            {-1, 0,  1,         0, -2,         0},
1587            {-1, 0,  2,         0, -3,         0},
1588            {-1, 0,  3,         0, -4,         0},
1589            {-1, 0,  3, 333333333, -5, 666666667},
1590
1591            {-1, 666666667, -4, 666666667,  3,         0},
1592            {-1, 666666667, -3,         0,  2, 666666667},
1593            {-1, 666666667, -2,         0,  1, 666666667},
1594            {-1, 666666667, -1,         0,  0, 666666667},
1595            {-1, 666666667, -1, 333333334,  0, 333333333},
1596            {-1, 666666667, -1, 666666667,  0,         0},
1597            {-1, 666666667, -1, 999999999, -1, 666666668},
1598            {-1, 666666667,  0,         0, -1, 666666667},
1599            {-1, 666666667,  0,         1, -1, 666666666},
1600            {-1, 666666667,  0, 333333333, -1, 333333334},
1601            {-1, 666666667,  0, 666666666, -1,         1},
1602            {-1, 666666667,  1,         0, -2, 666666667},
1603            {-1, 666666667,  2,         0, -3, 666666667},
1604            {-1, 666666667,  3,         0, -4, 666666667},
1605            {-1, 666666667,  3, 333333333, -4, 333333334},
1606
1607            {0, 0, -4, 666666667,  3, 333333333},
1608            {0, 0, -3,         0,  3,         0},
1609            {0, 0, -2,         0,  2,         0},
1610            {0, 0, -1,         0,  1,         0},
1611            {0, 0, -1, 333333334,  0, 666666666},
1612            {0, 0, -1, 666666667,  0, 333333333},
1613            {0, 0, -1, 999999999,  0,         1},
1614            {0, 0,  0,         0,  0,         0},
1615            {0, 0,  0,         1, -1, 999999999},
1616            {0, 0,  0, 333333333, -1, 666666667},
1617            {0, 0,  0, 666666666, -1, 333333334},
1618            {0, 0,  1,         0, -1,         0},
1619            {0, 0,  2,         0, -2,         0},
1620            {0, 0,  3,         0, -3,         0},
1621            {0, 0,  3, 333333333, -4, 666666667},
1622
1623            {0, 333333333, -4, 666666667,  3, 666666666},
1624            {0, 333333333, -3,         0,  3, 333333333},
1625            {0, 333333333, -2,         0,  2, 333333333},
1626            {0, 333333333, -1,         0,  1, 333333333},
1627            {0, 333333333, -1, 333333334,  0, 999999999},
1628            {0, 333333333, -1, 666666667,  0, 666666666},
1629            {0, 333333333, -1, 999999999,  0, 333333334},
1630            {0, 333333333,  0,         0,  0, 333333333},
1631            {0, 333333333,  0,         1,  0, 333333332},
1632            {0, 333333333,  0, 333333333,  0,         0},
1633            {0, 333333333,  0, 666666666, -1, 666666667},
1634            {0, 333333333,  1,         0, -1, 333333333},
1635            {0, 333333333,  2,         0, -2, 333333333},
1636            {0, 333333333,  3,         0, -3, 333333333},
1637            {0, 333333333,  3, 333333333, -3,         0},
1638
1639            {1, 0, -4, 666666667,  4, 333333333},
1640            {1, 0, -3,         0,  4,         0},
1641            {1, 0, -2,         0,  3,         0},
1642            {1, 0, -1,         0,  2,         0},
1643            {1, 0, -1, 333333334,  1, 666666666},
1644            {1, 0, -1, 666666667,  1, 333333333},
1645            {1, 0, -1, 999999999,  1,         1},
1646            {1, 0,  0,         0,  1,         0},
1647            {1, 0,  0,         1,  0, 999999999},
1648            {1, 0,  0, 333333333,  0, 666666667},
1649            {1, 0,  0, 666666666,  0, 333333334},
1650            {1, 0,  1,         0,  0,         0},
1651            {1, 0,  2,         0, -1,         0},
1652            {1, 0,  3,         0, -2,         0},
1653            {1, 0,  3, 333333333, -3, 666666667},
1654
1655            {2, 0, -4, 666666667,  5, 333333333},
1656            {2, 0, -3,         0,  5,         0},
1657            {2, 0, -2,         0,  4,         0},
1658            {2, 0, -1,         0,  3,         0},
1659            {2, 0, -1, 333333334,  2, 666666666},
1660            {2, 0, -1, 666666667,  2, 333333333},
1661            {2, 0, -1, 999999999,  2,         1},
1662            {2, 0,  0,         0,  2,         0},
1663            {2, 0,  0,         1,  1, 999999999},
1664            {2, 0,  0, 333333333,  1, 666666667},
1665            {2, 0,  0, 666666666,  1, 333333334},
1666            {2, 0,  1,         0,  1,         0},
1667            {2, 0,  2,         0,  0,         0},
1668            {2, 0,  3,         0, -1,         0},
1669            {2, 0,  3, 333333333, -2, 666666667},
1670
1671            {3, 0, -4, 666666667,  6, 333333333},
1672            {3, 0, -3,         0,  6,         0},
1673            {3, 0, -2,         0,  5,         0},
1674            {3, 0, -1,         0,  4,         0},
1675            {3, 0, -1, 333333334,  3, 666666666},
1676            {3, 0, -1, 666666667,  3, 333333333},
1677            {3, 0, -1, 999999999,  3,         1},
1678            {3, 0,  0,         0,  3,         0},
1679            {3, 0,  0,         1,  2, 999999999},
1680            {3, 0,  0, 333333333,  2, 666666667},
1681            {3, 0,  0, 666666666,  2, 333333334},
1682            {3, 0,  1,         0,  2,         0},
1683            {3, 0,  2,         0,  1,         0},
1684            {3, 0,  3,         0,  0,         0},
1685            {3, 0,  3, 333333333, -1, 666666667},
1686
1687            {3, 333333333, -4, 666666667,  6, 666666666},
1688            {3, 333333333, -3,         0,  6, 333333333},
1689            {3, 333333333, -2,         0,  5, 333333333},
1690            {3, 333333333, -1,         0,  4, 333333333},
1691            {3, 333333333, -1, 333333334,  3, 999999999},
1692            {3, 333333333, -1, 666666667,  3, 666666666},
1693            {3, 333333333, -1, 999999999,  3, 333333334},
1694            {3, 333333333,  0,         0,  3, 333333333},
1695            {3, 333333333,  0,         1,  3, 333333332},
1696            {3, 333333333,  0, 333333333,  3,         0},
1697            {3, 333333333,  0, 666666666,  2, 666666667},
1698            {3, 333333333,  1,         0,  2, 333333333},
1699            {3, 333333333,  2,         0,  1, 333333333},
1700            {3, 333333333,  3,         0,  0, 333333333},
1701            {3, 333333333,  3, 333333333,  0,         0},
1702
1703            {Long.MAX_VALUE, 0, Long.MAX_VALUE, 0, 0, 0},
1704       };
1705    }
1706
1707    @Test(dataProvider="Minus")
1708    public void minus(long seconds, int nanos, long otherSeconds, int otherNanos, long expectedSeconds, int expectedNanoOfSecond) {
1709       Duration t = Duration.ofSeconds(seconds, nanos).minus(Duration.ofSeconds(otherSeconds, otherNanos));
1710       assertEquals(t.getSeconds(), expectedSeconds);
1711       assertEquals(t.getNano(), expectedNanoOfSecond);
1712    }
1713
1714    @Test(expectedExceptions=ArithmeticException.class)
1715    public void minusOverflowTooSmall() {
1716       Duration t = Duration.ofSeconds(Long.MIN_VALUE);
1717       t.minus(Duration.ofSeconds(0, 1));
1718    }
1719
1720    @Test(expectedExceptions=ArithmeticException.class)
1721    public void minusOverflowTooBig() {
1722       Duration t = Duration.ofSeconds(Long.MAX_VALUE, 999999999);
1723       t.minus(Duration.ofSeconds(-1, 999999999));
1724    }
1725
1726    //-----------------------------------------------------------------------
1727    @Test
1728    public void minus_longTemporalUnit_seconds() {
1729        Duration t = Duration.ofSeconds(1);
1730        t = t.minus(1, SECONDS);
1731        assertEquals(0, t.getSeconds());
1732        assertEquals(0, t.getNano());
1733     }
1734
1735    @Test
1736    public void minus_longTemporalUnit_millis() {
1737        Duration t = Duration.ofSeconds(1);
1738        t = t.minus(1, MILLIS);
1739        assertEquals(0, t.getSeconds());
1740        assertEquals(999000000, t.getNano());
1741     }
1742
1743    @Test
1744    public void minus_longTemporalUnit_micros() {
1745        Duration t = Duration.ofSeconds(1);
1746        t = t.minus(1, MICROS);
1747        assertEquals(0, t.getSeconds());
1748        assertEquals(999999000, t.getNano());
1749     }
1750
1751    @Test
1752    public void minus_longTemporalUnit_nanos() {
1753        Duration t = Duration.ofSeconds(1);
1754        t = t.minus(1, NANOS);
1755        assertEquals(0, t.getSeconds());
1756        assertEquals(999999999, t.getNano());
1757     }
1758
1759    @Test(expectedExceptions=NullPointerException.class)
1760    public void minus_longTemporalUnit_null() {
1761       Duration t = Duration.ofSeconds(1);
1762       t.minus(1, (TemporalUnit) null);
1763    }
1764
1765    //-----------------------------------------------------------------------
1766    @DataProvider(name="MinusDays")
1767    Object[][] provider_minusDays_long() {
1768        return new Object[][] {
1769            {0, 0, 0},
1770            {0, 1, -1},
1771            {0, -1, 1},
1772            {Long.MAX_VALUE/3600/24, 0, Long.MAX_VALUE/3600/24},
1773            {Long.MIN_VALUE/3600/24, 0, Long.MIN_VALUE/3600/24},
1774            {1, 0, 1},
1775            {1, 1, 0},
1776            {1, -1, 2},
1777            {Long.MAX_VALUE/3600/24, 1, Long.MAX_VALUE/3600/24 - 1},
1778            {Long.MIN_VALUE/3600/24, -1, Long.MIN_VALUE/3600/24 + 1},
1779            {1, 0, 1},
1780            {1, 1, 0},
1781            {1, -1, 2},
1782            {-1, 0, -1},
1783            {-1, 1, -2},
1784            {-1, -1, 0},
1785        };
1786    }
1787
1788    @Test(dataProvider="MinusDays")
1789    public void minusDays_long(long days, long amount, long expectedDays) {
1790        Duration t = Duration.ofDays(days);
1791        t = t.minusDays(amount);
1792        assertEquals(t.toDays(), expectedDays);
1793    }
1794
1795    @Test(expectedExceptions = {ArithmeticException.class})
1796    public void minusDays_long_overflowTooBig() {
1797        Duration t = Duration.ofDays(Long.MAX_VALUE/3600/24);
1798        t.minusDays(-1);
1799    }
1800
1801    @Test(expectedExceptions = {ArithmeticException.class})
1802    public void minusDays_long_overflowTooSmall() {
1803        Duration t = Duration.ofDays(Long.MIN_VALUE/3600/24);
1804        t.minusDays(1);
1805    }
1806
1807    //-----------------------------------------------------------------------
1808    @DataProvider(name="MinusHours")
1809    Object[][] provider_minusHours_long() {
1810        return new Object[][] {
1811            {0, 0, 0},
1812            {0, 1, -1},
1813            {0, -1, 1},
1814            {Long.MAX_VALUE/3600, 0, Long.MAX_VALUE/3600},
1815            {Long.MIN_VALUE/3600, 0, Long.MIN_VALUE/3600},
1816            {1, 0, 1},
1817            {1, 1, 0},
1818            {1, -1, 2},
1819            {Long.MAX_VALUE/3600, 1, Long.MAX_VALUE/3600 - 1},
1820            {Long.MIN_VALUE/3600, -1, Long.MIN_VALUE/3600 + 1},
1821            {1, 0, 1},
1822            {1, 1, 0},
1823            {1, -1, 2},
1824            {-1, 0, -1},
1825            {-1, 1, -2},
1826            {-1, -1, 0},
1827        };
1828    }
1829
1830    @Test(dataProvider="MinusHours")
1831    public void minusHours_long(long hours, long amount, long expectedHours) {
1832        Duration t = Duration.ofHours(hours);
1833        t = t.minusHours(amount);
1834        assertEquals(t.toHours(), expectedHours);
1835    }
1836
1837    @Test(expectedExceptions = {ArithmeticException.class})
1838    public void minusHours_long_overflowTooBig() {
1839        Duration t = Duration.ofHours(Long.MAX_VALUE/3600);
1840        t.minusHours(-1);
1841    }
1842
1843    @Test(expectedExceptions = {ArithmeticException.class})
1844    public void minusHours_long_overflowTooSmall() {
1845        Duration t = Duration.ofHours(Long.MIN_VALUE/3600);
1846        t.minusHours(1);
1847    }
1848
1849    //-----------------------------------------------------------------------
1850    @DataProvider(name="MinusMinutes")
1851    Object[][] provider_minusminutes_long() {
1852        return new Object[][] {
1853            {0, 0, 0},
1854            {0, 1, -1},
1855            {0, -1, 1},
1856            {Long.MAX_VALUE/60, 0, Long.MAX_VALUE/60},
1857            {Long.MIN_VALUE/60, 0, Long.MIN_VALUE/60},
1858            {1, 0, 1},
1859            {1, 1, 0},
1860            {1, -1, 2},
1861            {Long.MAX_VALUE/60, 1, Long.MAX_VALUE/60 - 1},
1862            {Long.MIN_VALUE/60, -1, Long.MIN_VALUE/60 + 1},
1863            {1, 0, 1},
1864            {1, 1, 0},
1865            {1, -1, 2},
1866            {-1, 0, -1},
1867            {-1, 1, -2},
1868            {-1, -1, 0},
1869        };
1870    }
1871
1872    @Test(dataProvider="MinusMinutes")
1873    public void minusMinutes_long(long minutes, long amount, long expectedMinutes) {
1874        Duration t = Duration.ofMinutes(minutes);
1875        t = t.minusMinutes(amount);
1876        assertEquals(t.toMinutes(), expectedMinutes);
1877    }
1878
1879    @Test(expectedExceptions = {ArithmeticException.class})
1880    public void minusMinutes_long_overflowTooBig() {
1881        Duration t = Duration.ofMinutes(Long.MAX_VALUE/60);
1882        t.minusMinutes(-1);
1883    }
1884
1885    @Test(expectedExceptions = {ArithmeticException.class})
1886    public void minusMinutes_long_overflowTooSmall() {
1887        Duration t = Duration.ofMinutes(Long.MIN_VALUE/60);
1888        t.minusMinutes(1);
1889    }
1890
1891    //-----------------------------------------------------------------------
1892    @DataProvider(name="MinusSeconds")
1893    Object[][] provider_minusSeconds_long() {
1894        return new Object[][] {
1895            {0, 0, 0, 0, 0},
1896            {0, 0, 1, -1, 0},
1897            {0, 0, -1, 1, 0},
1898            {0, 0, Long.MAX_VALUE, -Long.MAX_VALUE, 0},
1899            {0, 0, Long.MIN_VALUE + 1, Long.MAX_VALUE, 0},
1900            {1, 0, 0, 1, 0},
1901            {1, 0, 1, 0, 0},
1902            {1, 0, -1, 2, 0},
1903            {1, 0, Long.MAX_VALUE - 1, -Long.MAX_VALUE + 2, 0},
1904            {1, 0, Long.MIN_VALUE + 2, Long.MAX_VALUE, 0},
1905            {1, 1, 0, 1, 1},
1906            {1, 1, 1, 0, 1},
1907            {1, 1, -1, 2, 1},
1908            {1, 1, Long.MAX_VALUE, -Long.MAX_VALUE + 1, 1},
1909            {1, 1, Long.MIN_VALUE + 2, Long.MAX_VALUE, 1},
1910            {-1, 1, 0, -1, 1},
1911            {-1, 1, 1, -2, 1},
1912            {-1, 1, -1, 0, 1},
1913            {-1, 1, Long.MAX_VALUE, Long.MIN_VALUE, 1},
1914            {-1, 1, Long.MIN_VALUE + 1, Long.MAX_VALUE - 1, 1},
1915        };
1916    }
1917
1918    @Test(dataProvider="MinusSeconds")
1919    public void minusSeconds_long(long seconds, int nanos, long amount, long expectedSeconds, int expectedNanoOfSecond) {
1920        Duration t = Duration.ofSeconds(seconds, nanos);
1921        t = t.minusSeconds(amount);
1922        assertEquals(t.getSeconds(), expectedSeconds);
1923        assertEquals(t.getNano(), expectedNanoOfSecond);
1924    }
1925
1926    @Test(expectedExceptions = {ArithmeticException.class})
1927    public void minusSeconds_long_overflowTooBig() {
1928        Duration t = Duration.ofSeconds(1, 0);
1929        t.minusSeconds(Long.MIN_VALUE + 1);
1930    }
1931
1932    @Test(expectedExceptions = {ArithmeticException.class})
1933    public void minusSeconds_long_overflowTooSmall() {
1934        Duration t = Duration.ofSeconds(-2, 0);
1935        t.minusSeconds(Long.MAX_VALUE);
1936    }
1937
1938    //-----------------------------------------------------------------------
1939    @DataProvider(name="MinusMillis")
1940    Object[][] provider_minusMillis_long() {
1941        return new Object[][] {
1942            {0, 0, 0,       0, 0},
1943            {0, 0, 1,      -1, 999000000},
1944            {0, 0, 999,    -1, 1000000},
1945            {0, 0, 1000,   -1, 0},
1946            {0, 0, 1001,   -2, 999000000},
1947            {0, 0, 1999,   -2, 1000000},
1948            {0, 0, 2000,   -2, 0},
1949            {0, 0, -1,      0, 1000000},
1950            {0, 0, -999,    0, 999000000},
1951            {0, 0, -1000,   1, 0},
1952            {0, 0, -1001,   1, 1000000},
1953            {0, 0, -1999,   1, 999000000},
1954
1955            {0, 1, 0,       0, 1},
1956            {0, 1, 1,      -1, 999000001},
1957            {0, 1, 998,    -1, 2000001},
1958            {0, 1, 999,    -1, 1000001},
1959            {0, 1, 1000,   -1, 1},
1960            {0, 1, 1998,   -2, 2000001},
1961            {0, 1, 1999,   -2, 1000001},
1962            {0, 1, 2000,   -2, 1},
1963            {0, 1, -1,      0, 1000001},
1964            {0, 1, -2,      0, 2000001},
1965            {0, 1, -1000,   1, 1},
1966            {0, 1, -1001,   1, 1000001},
1967
1968            {0, 1000000, 0,       0, 1000000},
1969            {0, 1000000, 1,       0, 0},
1970            {0, 1000000, 998,    -1, 3000000},
1971            {0, 1000000, 999,    -1, 2000000},
1972            {0, 1000000, 1000,   -1, 1000000},
1973            {0, 1000000, 1998,   -2, 3000000},
1974            {0, 1000000, 1999,   -2, 2000000},
1975            {0, 1000000, 2000,   -2, 1000000},
1976            {0, 1000000, -1,      0, 2000000},
1977            {0, 1000000, -2,      0, 3000000},
1978            {0, 1000000, -999,    1, 0},
1979            {0, 1000000, -1000,   1, 1000000},
1980            {0, 1000000, -1001,   1, 2000000},
1981            {0, 1000000, -1002,   1, 3000000},
1982
1983            {0, 999999999, 0,     0, 999999999},
1984            {0, 999999999, 1,     0, 998999999},
1985            {0, 999999999, 999,   0, 999999},
1986            {0, 999999999, 1000, -1, 999999999},
1987            {0, 999999999, 1001, -1, 998999999},
1988            {0, 999999999, -1,    1, 999999},
1989            {0, 999999999, -1000, 1, 999999999},
1990            {0, 999999999, -1001, 2, 999999},
1991        };
1992    }
1993
1994    @Test(dataProvider="MinusMillis")
1995    public void minusMillis_long(long seconds, int nanos, long amount, long expectedSeconds, int expectedNanoOfSecond) {
1996        Duration t = Duration.ofSeconds(seconds, nanos);
1997        t = t.minusMillis(amount);
1998        assertEquals(t.getSeconds(), expectedSeconds);
1999        assertEquals(t.getNano(), expectedNanoOfSecond);
2000    }
2001    @Test(dataProvider="MinusMillis")
2002    public void minusMillis_long_oneMore(long seconds, int nanos, long amount, long expectedSeconds, int expectedNanoOfSecond) {
2003        Duration t = Duration.ofSeconds(seconds + 1, nanos);
2004        t = t.minusMillis(amount);
2005        assertEquals(t.getSeconds(), expectedSeconds + 1);
2006        assertEquals(t.getNano(), expectedNanoOfSecond);
2007    }
2008    @Test(dataProvider="MinusMillis")
2009    public void minusMillis_long_minusOneLess(long seconds, int nanos, long amount, long expectedSeconds, int expectedNanoOfSecond) {
2010        Duration t = Duration.ofSeconds(seconds - 1, nanos);
2011        t = t.minusMillis(amount);
2012        assertEquals(t.getSeconds(), expectedSeconds - 1);
2013        assertEquals(t.getNano(), expectedNanoOfSecond);
2014    }
2015
2016    @Test
2017    public void minusMillis_long_max() {
2018        Duration t = Duration.ofSeconds(Long.MAX_VALUE, 998999999);
2019        t = t.minusMillis(-1);
2020        assertEquals(t.getSeconds(), Long.MAX_VALUE);
2021        assertEquals(t.getNano(), 999999999);
2022    }
2023
2024    @Test(expectedExceptions = {ArithmeticException.class})
2025    public void minusMillis_long_overflowTooBig() {
2026        Duration t = Duration.ofSeconds(Long.MAX_VALUE, 999000000);
2027        t.minusMillis(-1);
2028    }
2029
2030    @Test
2031    public void minusMillis_long_min() {
2032        Duration t = Duration.ofSeconds(Long.MIN_VALUE, 1000000);
2033        t = t.minusMillis(1);
2034        assertEquals(t.getSeconds(), Long.MIN_VALUE);
2035        assertEquals(t.getNano(), 0);
2036    }
2037
2038    @Test(expectedExceptions = {ArithmeticException.class})
2039    public void minusMillis_long_overflowTooSmall() {
2040        Duration t = Duration.ofSeconds(Long.MIN_VALUE, 0);
2041        t.minusMillis(1);
2042    }
2043
2044    //-----------------------------------------------------------------------
2045    @DataProvider(name="MinusNanos")
2046    Object[][] provider_minusNanos_long() {
2047        return new Object[][] {
2048            {0, 0, 0,           0, 0},
2049            {0, 0, 1,          -1, 999999999},
2050            {0, 0, 999999999,  -1, 1},
2051            {0, 0, 1000000000, -1, 0},
2052            {0, 0, 1000000001, -2, 999999999},
2053            {0, 0, 1999999999, -2, 1},
2054            {0, 0, 2000000000, -2, 0},
2055            {0, 0, -1,          0, 1},
2056            {0, 0, -999999999,  0, 999999999},
2057            {0, 0, -1000000000, 1, 0},
2058            {0, 0, -1000000001, 1, 1},
2059            {0, 0, -1999999999, 1, 999999999},
2060
2061            {1, 0, 0,            1, 0},
2062            {1, 0, 1,            0, 999999999},
2063            {1, 0, 999999999,    0, 1},
2064            {1, 0, 1000000000,   0, 0},
2065            {1, 0, 1000000001,  -1, 999999999},
2066            {1, 0, 1999999999,  -1, 1},
2067            {1, 0, 2000000000,  -1, 0},
2068            {1, 0, -1,           1, 1},
2069            {1, 0, -999999999,   1, 999999999},
2070            {1, 0, -1000000000,  2, 0},
2071            {1, 0, -1000000001,  2, 1},
2072            {1, 0, -1999999999,  2, 999999999},
2073
2074            {-1, 0, 0,           -1, 0},
2075            {-1, 0, 1,           -2, 999999999},
2076            {-1, 0, 999999999,   -2, 1},
2077            {-1, 0, 1000000000,  -2, 0},
2078            {-1, 0, 1000000001,  -3, 999999999},
2079            {-1, 0, 1999999999,  -3, 1},
2080            {-1, 0, 2000000000,  -3, 0},
2081            {-1, 0, -1,          -1, 1},
2082            {-1, 0, -999999999,  -1, 999999999},
2083            {-1, 0, -1000000000,  0, 0},
2084            {-1, 0, -1000000001,  0, 1},
2085            {-1, 0, -1999999999,  0, 999999999},
2086
2087            {1, 1, 0,           1, 1},
2088            {1, 1, 1,           1, 0},
2089            {1, 1, 999999998,   0, 3},
2090            {1, 1, 999999999,   0, 2},
2091            {1, 1, 1000000000,  0, 1},
2092            {1, 1, 1999999998, -1, 3},
2093            {1, 1, 1999999999, -1, 2},
2094            {1, 1, 2000000000, -1, 1},
2095            {1, 1, -1,          1, 2},
2096            {1, 1, -2,          1, 3},
2097            {1, 1, -1000000000, 2, 1},
2098            {1, 1, -1000000001, 2, 2},
2099            {1, 1, -1000000002, 2, 3},
2100            {1, 1, -2000000000, 3, 1},
2101
2102            {1, 999999999, 0,           1, 999999999},
2103            {1, 999999999, 1,           1, 999999998},
2104            {1, 999999999, 999999999,   1, 0},
2105            {1, 999999999, 1000000000,  0, 999999999},
2106            {1, 999999999, 1000000001,  0, 999999998},
2107            {1, 999999999, -1,          2, 0},
2108            {1, 999999999, -1000000000, 2, 999999999},
2109            {1, 999999999, -1000000001, 3, 0},
2110            {1, 999999999, -1999999999, 3, 999999998},
2111            {1, 999999999, -2000000000, 3, 999999999},
2112
2113            {Long.MAX_VALUE, 0, -999999999, Long.MAX_VALUE, 999999999},
2114            {Long.MAX_VALUE - 1, 0, -1999999999, Long.MAX_VALUE, 999999999},
2115            {Long.MIN_VALUE, 1, 1, Long.MIN_VALUE, 0},
2116            {Long.MIN_VALUE + 1, 1, 1000000001, Long.MIN_VALUE, 0},
2117        };
2118    }
2119
2120    @Test(dataProvider="MinusNanos")
2121    public void minusNanos_long(long seconds, int nanos, long amount, long expectedSeconds, int expectedNanoOfSecond) {
2122        Duration t = Duration.ofSeconds(seconds, nanos);
2123        t = t.minusNanos(amount);
2124        assertEquals(t.getSeconds(), expectedSeconds);
2125        assertEquals(t.getNano(), expectedNanoOfSecond);
2126    }
2127
2128    @Test(expectedExceptions = {ArithmeticException.class})
2129    public void minusNanos_long_overflowTooBig() {
2130        Duration t = Duration.ofSeconds(Long.MAX_VALUE, 999999999);
2131        t.minusNanos(-1);
2132    }
2133
2134    @Test(expectedExceptions = {ArithmeticException.class})
2135    public void minusNanos_long_overflowTooSmall() {
2136        Duration t = Duration.ofSeconds(Long.MIN_VALUE, 0);
2137        t.minusNanos(1);
2138    }
2139
2140    //-----------------------------------------------------------------------
2141    // multipliedBy()
2142    //-----------------------------------------------------------------------
2143    @DataProvider(name="MultipliedBy")
2144    Object[][] provider_multipliedBy() {
2145       return new Object[][] {
2146          {-4, 666666667, -3,   9, 999999999},
2147          {-4, 666666667, -2,   6, 666666666},
2148          {-4, 666666667, -1,   3, 333333333},
2149          {-4, 666666667,  0,   0,         0},
2150          {-4, 666666667,  1,  -4, 666666667},
2151          {-4, 666666667,  2,  -7, 333333334},
2152          {-4, 666666667,  3, -10, 000000001},
2153
2154          {-3, 0, -3,  9, 0},
2155          {-3, 0, -2,  6, 0},
2156          {-3, 0, -1,  3, 0},
2157          {-3, 0,  0,  0, 0},
2158          {-3, 0,  1, -3, 0},
2159          {-3, 0,  2, -6, 0},
2160          {-3, 0,  3, -9, 0},
2161
2162          {-2, 0, -3,  6, 0},
2163          {-2, 0, -2,  4, 0},
2164          {-2, 0, -1,  2, 0},
2165          {-2, 0,  0,  0, 0},
2166          {-2, 0,  1, -2, 0},
2167          {-2, 0,  2, -4, 0},
2168          {-2, 0,  3, -6, 0},
2169
2170          {-1, 0, -3,  3, 0},
2171          {-1, 0, -2,  2, 0},
2172          {-1, 0, -1,  1, 0},
2173          {-1, 0,  0,  0, 0},
2174          {-1, 0,  1, -1, 0},
2175          {-1, 0,  2, -2, 0},
2176          {-1, 0,  3, -3, 0},
2177
2178          {-1, 500000000, -3,  1, 500000000},
2179          {-1, 500000000, -2,  1,         0},
2180          {-1, 500000000, -1,  0, 500000000},
2181          {-1, 500000000,  0,  0,         0},
2182          {-1, 500000000,  1, -1, 500000000},
2183          {-1, 500000000,  2, -1,         0},
2184          {-1, 500000000,  3, -2, 500000000},
2185
2186          {0, 0, -3, 0, 0},
2187          {0, 0, -2, 0, 0},
2188          {0, 0, -1, 0, 0},
2189          {0, 0,  0, 0, 0},
2190          {0, 0,  1, 0, 0},
2191          {0, 0,  2, 0, 0},
2192          {0, 0,  3, 0, 0},
2193
2194          {0, 500000000, -3, -2, 500000000},
2195          {0, 500000000, -2, -1,         0},
2196          {0, 500000000, -1, -1, 500000000},
2197          {0, 500000000,  0,  0,         0},
2198          {0, 500000000,  1,  0, 500000000},
2199          {0, 500000000,  2,  1,         0},
2200          {0, 500000000,  3,  1, 500000000},
2201
2202          {1, 0, -3, -3, 0},
2203          {1, 0, -2, -2, 0},
2204          {1, 0, -1, -1, 0},
2205          {1, 0,  0,  0, 0},
2206          {1, 0,  1,  1, 0},
2207          {1, 0,  2,  2, 0},
2208          {1, 0,  3,  3, 0},
2209
2210          {2, 0, -3, -6, 0},
2211          {2, 0, -2, -4, 0},
2212          {2, 0, -1, -2, 0},
2213          {2, 0,  0,  0, 0},
2214          {2, 0,  1,  2, 0},
2215          {2, 0,  2,  4, 0},
2216          {2, 0,  3,  6, 0},
2217
2218          {3, 0, -3, -9, 0},
2219          {3, 0, -2, -6, 0},
2220          {3, 0, -1, -3, 0},
2221          {3, 0,  0,  0, 0},
2222          {3, 0,  1,  3, 0},
2223          {3, 0,  2,  6, 0},
2224          {3, 0,  3,  9, 0},
2225
2226          {3, 333333333, -3, -10, 000000001},
2227          {3, 333333333, -2,  -7, 333333334},
2228          {3, 333333333, -1,  -4, 666666667},
2229          {3, 333333333,  0,   0,         0},
2230          {3, 333333333,  1,   3, 333333333},
2231          {3, 333333333,  2,   6, 666666666},
2232          {3, 333333333,  3,   9, 999999999},
2233       };
2234    }
2235
2236    @Test(dataProvider="MultipliedBy")
2237    public void multipliedBy(long seconds, int nanos, int multiplicand, long expectedSeconds, int expectedNanos) {
2238        Duration t = Duration.ofSeconds(seconds, nanos);
2239        t = t.multipliedBy(multiplicand);
2240        assertEquals(t.getSeconds(), expectedSeconds);
2241        assertEquals(t.getNano(), expectedNanos);
2242    }
2243
2244    @Test
2245    public void multipliedBy_max() {
2246        Duration test = Duration.ofSeconds(1);
2247        assertEquals(test.multipliedBy(Long.MAX_VALUE), Duration.ofSeconds(Long.MAX_VALUE));
2248    }
2249
2250    @Test
2251    public void multipliedBy_min() {
2252        Duration test = Duration.ofSeconds(1);
2253        assertEquals(test.multipliedBy(Long.MIN_VALUE), Duration.ofSeconds(Long.MIN_VALUE));
2254    }
2255
2256    @Test(expectedExceptions=ArithmeticException.class)
2257    public void multipliedBy_tooBig() {
2258        Duration test = Duration.ofSeconds(1, 1);
2259        test.multipliedBy(Long.MAX_VALUE);
2260    }
2261
2262    @Test(expectedExceptions=ArithmeticException.class)
2263    public void multipliedBy_tooBig_negative() {
2264        Duration test = Duration.ofSeconds(1, 1);
2265        test.multipliedBy(Long.MIN_VALUE);
2266    }
2267
2268    //-----------------------------------------------------------------------
2269    // dividedBy()
2270    //-----------------------------------------------------------------------
2271    @DataProvider(name="DividedBy")
2272    Object[][] provider_dividedBy() {
2273       return new Object[][] {
2274          {-4, 666666667, -3,  1, 111111111},
2275          {-4, 666666667, -2,  1, 666666666},
2276          {-4, 666666667, -1,  3, 333333333},
2277          {-4, 666666667,  1, -4, 666666667},
2278          {-4, 666666667,  2, -2, 333333334},
2279          {-4, 666666667,  3, -2, 888888889},
2280
2281          {-3, 0, -3,  1, 0},
2282          {-3, 0, -2,  1, 500000000},
2283          {-3, 0, -1,  3, 0},
2284          {-3, 0,  1, -3, 0},
2285          {-3, 0,  2, -2, 500000000},
2286          {-3, 0,  3, -1, 0},
2287
2288          {-2, 0, -3,  0, 666666666},
2289          {-2, 0, -2,  1,         0},
2290          {-2, 0, -1,  2,         0},
2291          {-2, 0,  1, -2,         0},
2292          {-2, 0,  2, -1,         0},
2293          {-2, 0,  3, -1, 333333334},
2294
2295          {-1, 0, -3,  0, 333333333},
2296          {-1, 0, -2,  0, 500000000},
2297          {-1, 0, -1,  1,         0},
2298          {-1, 0,  1, -1,         0},
2299          {-1, 0,  2, -1, 500000000},
2300          {-1, 0,  3, -1, 666666667},
2301
2302          {-1, 500000000, -3,  0, 166666666},
2303          {-1, 500000000, -2,  0, 250000000},
2304          {-1, 500000000, -1,  0, 500000000},
2305          {-1, 500000000,  1, -1, 500000000},
2306          {-1, 500000000,  2, -1, 750000000},
2307          {-1, 500000000,  3, -1, 833333334},
2308
2309          {0, 0, -3, 0, 0},
2310          {0, 0, -2, 0, 0},
2311          {0, 0, -1, 0, 0},
2312          {0, 0,  1, 0, 0},
2313          {0, 0,  2, 0, 0},
2314          {0, 0,  3, 0, 0},
2315
2316          {0, 500000000, -3, -1, 833333334},
2317          {0, 500000000, -2, -1, 750000000},
2318          {0, 500000000, -1, -1, 500000000},
2319          {0, 500000000,  1,  0, 500000000},
2320          {0, 500000000,  2,  0, 250000000},
2321          {0, 500000000,  3,  0, 166666666},
2322
2323          {1, 0, -3, -1, 666666667},
2324          {1, 0, -2, -1, 500000000},
2325          {1, 0, -1, -1,         0},
2326          {1, 0,  1,  1,         0},
2327          {1, 0,  2,  0, 500000000},
2328          {1, 0,  3,  0, 333333333},
2329
2330          {2, 0, -3, -1, 333333334},
2331          {2, 0, -2, -1,         0},
2332          {2, 0, -1, -2,         0},
2333          {2, 0,  1,  2,         0},
2334          {2, 0,  2,  1,         0},
2335          {2, 0,  3,  0, 666666666},
2336
2337          {3, 0, -3, -1,         0},
2338          {3, 0, -2, -2, 500000000},
2339          {3, 0, -1, -3,         0},
2340          {3, 0,  1,  3,         0},
2341          {3, 0,  2,  1, 500000000},
2342          {3, 0,  3,  1,         0},
2343
2344          {3, 333333333, -3, -2, 888888889},
2345          {3, 333333333, -2, -2, 333333334},
2346          {3, 333333333, -1, -4, 666666667},
2347          {3, 333333333,  1,  3, 333333333},
2348          {3, 333333333,  2,  1, 666666666},
2349          {3, 333333333,  3,  1, 111111111},
2350       };
2351    }
2352
2353    @Test(dataProvider="DividedBy")
2354    public void dividedBy(long seconds, int nanos, int divisor, long expectedSeconds, int expectedNanos) {
2355        Duration t = Duration.ofSeconds(seconds, nanos);
2356        t = t.dividedBy(divisor);
2357        assertEquals(t.getSeconds(), expectedSeconds);
2358        assertEquals(t.getNano(), expectedNanos);
2359    }
2360
2361    @Test(dataProvider="DividedBy", expectedExceptions=ArithmeticException.class)
2362    public void dividedByZero(long seconds, int nanos, int divisor, long expectedSeconds, int expectedNanos) {
2363       Duration t = Duration.ofSeconds(seconds, nanos);
2364       t.dividedBy(0);
2365       fail(t + " divided by zero did not throw ArithmeticException");
2366    }
2367
2368    @Test
2369    public void dividedBy_max() {
2370        Duration test = Duration.ofSeconds(Long.MAX_VALUE);
2371        assertEquals(test.dividedBy(Long.MAX_VALUE), Duration.ofSeconds(1));
2372    }
2373
2374    //-----------------------------------------------------------------------
2375    // negated()
2376    //-----------------------------------------------------------------------
2377    @Test
2378    public void test_negated() {
2379        assertEquals(Duration.ofSeconds(0).negated(), Duration.ofSeconds(0));
2380        assertEquals(Duration.ofSeconds(12).negated(), Duration.ofSeconds(-12));
2381        assertEquals(Duration.ofSeconds(-12).negated(), Duration.ofSeconds(12));
2382        assertEquals(Duration.ofSeconds(12, 20).negated(), Duration.ofSeconds(-12, -20));
2383        assertEquals(Duration.ofSeconds(12, -20).negated(), Duration.ofSeconds(-12, 20));
2384        assertEquals(Duration.ofSeconds(-12, -20).negated(), Duration.ofSeconds(12, 20));
2385        assertEquals(Duration.ofSeconds(-12, 20).negated(), Duration.ofSeconds(12, -20));
2386        assertEquals(Duration.ofSeconds(Long.MAX_VALUE).negated(), Duration.ofSeconds(-Long.MAX_VALUE));
2387    }
2388
2389    @Test(expectedExceptions=ArithmeticException.class)
2390    public void test_negated_overflow() {
2391        Duration.ofSeconds(Long.MIN_VALUE).negated();
2392    }
2393
2394    //-----------------------------------------------------------------------
2395    // abs()
2396    //-----------------------------------------------------------------------
2397    @Test
2398    public void test_abs() {
2399        assertEquals(Duration.ofSeconds(0).abs(), Duration.ofSeconds(0));
2400        assertEquals(Duration.ofSeconds(12).abs(), Duration.ofSeconds(12));
2401        assertEquals(Duration.ofSeconds(-12).abs(), Duration.ofSeconds(12));
2402        assertEquals(Duration.ofSeconds(12, 20).abs(), Duration.ofSeconds(12, 20));
2403        assertEquals(Duration.ofSeconds(12, -20).abs(), Duration.ofSeconds(12, -20));
2404        assertEquals(Duration.ofSeconds(-12, -20).abs(), Duration.ofSeconds(12, 20));
2405        assertEquals(Duration.ofSeconds(-12, 20).abs(), Duration.ofSeconds(12, -20));
2406        assertEquals(Duration.ofSeconds(Long.MAX_VALUE).abs(), Duration.ofSeconds(Long.MAX_VALUE));
2407    }
2408
2409    @Test(expectedExceptions=ArithmeticException.class)
2410    public void test_abs_overflow() {
2411        Duration.ofSeconds(Long.MIN_VALUE).abs();
2412    }
2413
2414    //-----------------------------------------------------------------------
2415    // toNanos()
2416    //-----------------------------------------------------------------------
2417    @Test
2418    public void test_toNanos() {
2419        Duration test = Duration.ofSeconds(321, 123456789);
2420        assertEquals(test.toNanos(), 321123456789L);
2421    }
2422
2423    @Test
2424    public void test_toNanos_max() {
2425        Duration test = Duration.ofSeconds(0, Long.MAX_VALUE);
2426        assertEquals(test.toNanos(), Long.MAX_VALUE);
2427    }
2428
2429    @Test(expectedExceptions=ArithmeticException.class)
2430    public void test_toNanos_tooBig() {
2431        Duration test = Duration.ofSeconds(0, Long.MAX_VALUE).plusNanos(1);
2432        test.toNanos();
2433    }
2434
2435    //-----------------------------------------------------------------------
2436    // toMillis()
2437    //-----------------------------------------------------------------------
2438    @Test
2439    public void test_toMillis() {
2440        Duration test = Duration.ofSeconds(321, 123456789);
2441        assertEquals(test.toMillis(), 321000 + 123);
2442    }
2443
2444    @Test
2445    public void test_toMillis_max() {
2446        Duration test = Duration.ofSeconds(Long.MAX_VALUE / 1000, (Long.MAX_VALUE % 1000) * 1000000);
2447        assertEquals(test.toMillis(), Long.MAX_VALUE);
2448    }
2449
2450    @Test(expectedExceptions=ArithmeticException.class)
2451    public void test_toMillis_tooBig() {
2452        Duration test = Duration.ofSeconds(Long.MAX_VALUE / 1000, ((Long.MAX_VALUE % 1000) + 1) * 1000000);
2453        test.toMillis();
2454    }
2455
2456    //-----------------------------------------------------------------------
2457    // compareTo()
2458    //-----------------------------------------------------------------------
2459    @Test
2460    public void test_comparisons() {
2461        doTest_comparisons_Duration(
2462            Duration.ofSeconds(-2L, 0),
2463            Duration.ofSeconds(-2L, 999999998),
2464            Duration.ofSeconds(-2L, 999999999),
2465            Duration.ofSeconds(-1L, 0),
2466            Duration.ofSeconds(-1L, 1),
2467            Duration.ofSeconds(-1L, 999999998),
2468            Duration.ofSeconds(-1L, 999999999),
2469            Duration.ofSeconds(0L, 0),
2470            Duration.ofSeconds(0L, 1),
2471            Duration.ofSeconds(0L, 2),
2472            Duration.ofSeconds(0L, 999999999),
2473            Duration.ofSeconds(1L, 0),
2474            Duration.ofSeconds(2L, 0)
2475        );
2476    }
2477
2478    void doTest_comparisons_Duration(Duration... durations) {
2479        for (int i = 0; i < durations.length; i++) {
2480            Duration a = durations[i];
2481            for (int j = 0; j < durations.length; j++) {
2482                Duration b = durations[j];
2483                if (i < j) {
2484                    assertEquals(a.compareTo(b)< 0, true, a + " <=> " + b);
2485                    assertEquals(a.equals(b), false, a + " <=> " + b);
2486                } else if (i > j) {
2487                    assertEquals(a.compareTo(b) > 0, true, a + " <=> " + b);
2488                    assertEquals(a.equals(b), false, a + " <=> " + b);
2489                } else {
2490                    assertEquals(a.compareTo(b), 0, a + " <=> " + b);
2491                    assertEquals(a.equals(b), true, a + " <=> " + b);
2492                }
2493            }
2494        }
2495    }
2496
2497    @Test(expectedExceptions=NullPointerException.class)
2498    public void test_compareTo_ObjectNull() {
2499        Duration a = Duration.ofSeconds(0L, 0);
2500        a.compareTo(null);
2501    }
2502
2503    @Test(expectedExceptions=ClassCastException.class)
2504    @SuppressWarnings({ "unchecked", "rawtypes" })
2505    public void compareToNonDuration() {
2506       Comparable c = Duration.ofSeconds(0L);
2507       c.compareTo(new Object());
2508    }
2509
2510    //-----------------------------------------------------------------------
2511    // equals()
2512    //-----------------------------------------------------------------------
2513    @Test
2514    public void test_equals() {
2515        Duration test5a = Duration.ofSeconds(5L, 20);
2516        Duration test5b = Duration.ofSeconds(5L, 20);
2517        Duration test5n = Duration.ofSeconds(5L, 30);
2518        Duration test6 = Duration.ofSeconds(6L, 20);
2519
2520        assertEquals(test5a.equals(test5a), true);
2521        assertEquals(test5a.equals(test5b), true);
2522        assertEquals(test5a.equals(test5n), false);
2523        assertEquals(test5a.equals(test6), false);
2524
2525        assertEquals(test5b.equals(test5a), true);
2526        assertEquals(test5b.equals(test5b), true);
2527        assertEquals(test5b.equals(test5n), false);
2528        assertEquals(test5b.equals(test6), false);
2529
2530        assertEquals(test5n.equals(test5a), false);
2531        assertEquals(test5n.equals(test5b), false);
2532        assertEquals(test5n.equals(test5n), true);
2533        assertEquals(test5n.equals(test6), false);
2534
2535        assertEquals(test6.equals(test5a), false);
2536        assertEquals(test6.equals(test5b), false);
2537        assertEquals(test6.equals(test5n), false);
2538        assertEquals(test6.equals(test6), true);
2539    }
2540
2541    @Test
2542    public void test_equals_null() {
2543        Duration test5 = Duration.ofSeconds(5L, 20);
2544        assertEquals(test5.equals(null), false);
2545    }
2546
2547    @Test
2548    public void test_equals_otherClass() {
2549        Duration test5 = Duration.ofSeconds(5L, 20);
2550        assertEquals(test5.equals(""), false);
2551    }
2552
2553    //-----------------------------------------------------------------------
2554    // hashCode()
2555    //-----------------------------------------------------------------------
2556    @Test
2557    public void test_hashCode() {
2558        Duration test5a = Duration.ofSeconds(5L, 20);
2559        Duration test5b = Duration.ofSeconds(5L, 20);
2560        Duration test5n = Duration.ofSeconds(5L, 30);
2561        Duration test6 = Duration.ofSeconds(6L, 20);
2562
2563        assertEquals(test5a.hashCode() == test5a.hashCode(), true);
2564        assertEquals(test5a.hashCode() == test5b.hashCode(), true);
2565        assertEquals(test5b.hashCode() == test5b.hashCode(), true);
2566
2567        assertEquals(test5a.hashCode() == test5n.hashCode(), false);
2568        assertEquals(test5a.hashCode() == test6.hashCode(), false);
2569    }
2570
2571    //-----------------------------------------------------------------------
2572    @DataProvider(name="withNanos")
2573    Object[][] provider_withNanos_int() {
2574        return new Object[][] {
2575            {0, 0, 0,           0, 0},
2576            {0, 0, 1,           0, 1},
2577            {0, 0, 999999999,   0, 999999999},
2578
2579            {1, 0, 0,           1, 0},
2580            {1, 0, 1,           1, 1},
2581            {1, 0, 999999999,   1, 999999999},
2582
2583            {-1, 0, 0,           -1, 0},
2584            {-1, 0, 1,           -1, 1},
2585            {-1, 0, 999999999,   -1, 999999999},
2586
2587            {1, 999999999, 0,           1, 0},
2588            {1, 999999999, 1,           1, 1},
2589            {1, 999999998, 2,           1, 2},
2590
2591            {Long.MAX_VALUE, 0, 999999999, Long.MAX_VALUE, 999999999},
2592            {Long.MIN_VALUE, 0, 999999999, Long.MIN_VALUE, 999999999},
2593        };
2594    }
2595
2596    @Test(dataProvider="withNanos")
2597    public void withNanos_long(long seconds, int nanos, int amount, long expectedSeconds, int expectedNanoOfSecond) {
2598        Duration t = Duration.ofSeconds(seconds, nanos);
2599        t = t.withNanos(amount);
2600        assertEquals(t.getSeconds(), expectedSeconds);
2601        assertEquals(t.getNano(), expectedNanoOfSecond);
2602    }
2603
2604    //-----------------------------------------------------------------------
2605    @DataProvider(name="withSeconds")
2606    Object[][] provider_withSeconds_long() {
2607        return new Object[][] {
2608            {0, 0, 0, 0, 0},
2609            {0, 0, 1, 1, 0},
2610            {0, 0, -1, -1, 0},
2611            {0, 0, Long.MAX_VALUE, Long.MAX_VALUE, 0},
2612            {0, 0, Long.MIN_VALUE, Long.MIN_VALUE, 0},
2613
2614            {1, 0, 0, 0, 0},
2615            {1, 0, 2, 2, 0},
2616            {1, 0, -1, -1, 0},
2617            {1, 0, Long.MAX_VALUE, Long.MAX_VALUE, 0},
2618            {1, 0, Long.MIN_VALUE, Long.MIN_VALUE, 0},
2619
2620            {-1, 1, 0, 0, 1},
2621            {-1, 1, 1, 1, 1},
2622            {-1, 1, -1, -1, 1},
2623            {-1, 1, Long.MAX_VALUE, Long.MAX_VALUE, 1},
2624            {-1, 1, Long.MIN_VALUE, Long.MIN_VALUE, 1},
2625        };
2626    }
2627
2628    @Test(dataProvider="withSeconds")
2629    public void withSeconds_long(long seconds, int nanos, long amount, long expectedSeconds, int expectedNanoOfSecond) {
2630        Duration t = Duration.ofSeconds(seconds, nanos);
2631        t = t.withSeconds(amount);
2632        assertEquals(t.getSeconds(), expectedSeconds);
2633        assertEquals(t.getNano(), expectedNanoOfSecond);
2634    }
2635
2636    //-----------------------------------------------------------------------
2637    // toString()
2638    //-----------------------------------------------------------------------
2639    @DataProvider(name="toString")
2640    Object[][] provider_toString() {
2641        return new Object[][] {
2642            {0, 0, "PT0S"},
2643            {0, 1, "PT0.000000001S"},
2644            {0, 10, "PT0.00000001S"},
2645            {0, 100, "PT0.0000001S"},
2646            {0, 1000, "PT0.000001S"},
2647            {0, 10000, "PT0.00001S"},
2648            {0, 100000, "PT0.0001S"},
2649            {0, 1000000, "PT0.001S"},
2650            {0, 10000000, "PT0.01S"},
2651            {0, 100000000, "PT0.1S"},
2652            {0, 120000000, "PT0.12S"},
2653            {0, 123000000, "PT0.123S"},
2654            {0, 123400000, "PT0.1234S"},
2655            {0, 123450000, "PT0.12345S"},
2656            {0, 123456000, "PT0.123456S"},
2657            {0, 123456700, "PT0.1234567S"},
2658            {0, 123456780, "PT0.12345678S"},
2659            {0, 123456789, "PT0.123456789S"},
2660            {1, 0, "PT1S"},
2661            {59, 0, "PT59S"},
2662            {60, 0, "PT1M"},
2663            {61, 0, "PT1M1S"},
2664            {3599, 0, "PT59M59S"},
2665            {3600, 0, "PT1H"},
2666            {3601, 0, "PT1H1S"},
2667            {3661, 0, "PT1H1M1S"},
2668            {86399, 0, "PT23H59M59S"},
2669            {86400, 0, "PT24H"},
2670            {59, 0, "PT59S"},
2671            {59, 0, "PT59S"},
2672            {-1, 0, "PT-1S"},
2673            {-1, 1000, "PT-0.999999S"},
2674            {-1, 900000000, "PT-0.1S"},
2675            {Long.MAX_VALUE, 0, "PT" + (Long.MAX_VALUE / 3600) + "H" +
2676                    ((Long.MAX_VALUE % 3600) / 60) + "M" + (Long.MAX_VALUE % 60) + "S"},
2677            {Long.MIN_VALUE, 0, "PT" + (Long.MIN_VALUE / 3600) + "H" +
2678                    ((Long.MIN_VALUE % 3600) / 60) + "M" + (Long.MIN_VALUE % 60) + "S"},
2679        };
2680    }
2681
2682    @Test(dataProvider="toString")
2683    public void test_toString(long seconds, int nanos, String expected) {
2684        Duration t = Duration.ofSeconds(seconds, nanos);
2685        assertEquals(t.toString(), expected);
2686    }
2687
2688    //-----------------------------------------------------------------------
2689    @Test(groups="{tck}")
2690    public void test_duration_getUnits() {
2691        Duration duration = Duration.ofSeconds(5000, 1000);
2692        List<TemporalUnit> units = duration.getUnits();
2693        assertEquals(units.size(), 2, "Period.getUnits length");
2694        assertTrue(units.contains(ChronoUnit.SECONDS), "Period.getUnits contains ChronoUnit.SECONDS");
2695        assertTrue(units.contains(ChronoUnit.NANOS), "contains ChronoUnit.NANOS");
2696    }
2697
2698    @Test()
2699    public void test_getUnit() {
2700        Duration test = Duration.ofSeconds(2000, 1000);
2701        long seconds = test.get(ChronoUnit.SECONDS);
2702        assertEquals(seconds, 2000, "duration.get(SECONDS)");
2703        long nanos = test.get(ChronoUnit.NANOS);
2704        assertEquals(nanos, 1000, "duration.get(NANOS)");
2705    }
2706
2707    @DataProvider(name="BadTemporalUnit")
2708    Object[][] provider_factory_of_badTemporalUnit() {
2709        return new Object[][] {
2710            {0, MICROS},
2711            {0, MILLIS},
2712            {0, MINUTES},
2713            {0, HOURS},
2714            {0, HALF_DAYS},
2715            {0, DAYS},
2716            {0, ChronoUnit.MONTHS},
2717            {0, ChronoUnit.YEARS},
2718            {0, ChronoUnit.DECADES},
2719            {0, ChronoUnit.CENTURIES},
2720            {0, ChronoUnit.MILLENNIA},
2721        };
2722    }
2723
2724    @Test(dataProvider="BadTemporalUnit", expectedExceptions=DateTimeException.class)
2725    public void test_bad_getUnit(long amount, TemporalUnit unit) {
2726        Duration t = Duration.of(amount, unit);
2727        t.get(unit);
2728    }
2729}
2730