1/*
2 * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/*
25 * This file is available under and governed by the GNU General Public
26 * License version 2 only, as published by the Free Software Foundation.
27 * However, the following notice accompanied the original version of this
28 * file:
29 *
30 * Copyright (c) 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.ChronoField.AMPM_OF_DAY;
63import static java.time.temporal.ChronoField.CLOCK_HOUR_OF_AMPM;
64import static java.time.temporal.ChronoField.CLOCK_HOUR_OF_DAY;
65import static java.time.temporal.ChronoField.HOUR_OF_AMPM;
66import static java.time.temporal.ChronoField.HOUR_OF_DAY;
67import static java.time.temporal.ChronoField.MICRO_OF_DAY;
68import static java.time.temporal.ChronoField.MICRO_OF_SECOND;
69import static java.time.temporal.ChronoField.MILLI_OF_DAY;
70import static java.time.temporal.ChronoField.MILLI_OF_SECOND;
71import static java.time.temporal.ChronoField.MINUTE_OF_DAY;
72import static java.time.temporal.ChronoField.MINUTE_OF_HOUR;
73import static java.time.temporal.ChronoField.NANO_OF_DAY;
74import static java.time.temporal.ChronoField.NANO_OF_SECOND;
75import static java.time.temporal.ChronoField.SECOND_OF_DAY;
76import static java.time.temporal.ChronoField.SECOND_OF_MINUTE;
77import static java.time.temporal.ChronoUnit.DAYS;
78import static java.time.temporal.ChronoUnit.FOREVER;
79import static java.time.temporal.ChronoUnit.HALF_DAYS;
80import static java.time.temporal.ChronoUnit.HOURS;
81import static java.time.temporal.ChronoUnit.MICROS;
82import static java.time.temporal.ChronoUnit.MILLIS;
83import static java.time.temporal.ChronoUnit.MINUTES;
84import static java.time.temporal.ChronoUnit.MONTHS;
85import static java.time.temporal.ChronoUnit.NANOS;
86import static java.time.temporal.ChronoUnit.SECONDS;
87import static java.time.temporal.ChronoUnit.WEEKS;
88import static java.time.temporal.ChronoUnit.YEARS;
89import static org.testng.Assert.assertEquals;
90import static org.testng.Assert.assertNotNull;
91import static org.testng.Assert.assertSame;
92import static org.testng.Assert.assertTrue;
93import static org.testng.Assert.fail;
94
95import java.time.Clock;
96import java.time.DateTimeException;
97import java.time.Duration;
98import java.time.Instant;
99import java.time.LocalDate;
100import java.time.LocalDateTime;
101import java.time.LocalTime;
102import java.time.OffsetDateTime;
103import java.time.OffsetTime;
104import java.time.Period;
105import java.time.Year;
106import java.time.ZoneId;
107import java.time.ZoneOffset;
108import java.time.ZonedDateTime;
109import java.time.format.DateTimeFormatter;
110import java.time.format.DateTimeParseException;
111import java.time.temporal.ChronoField;
112import java.time.temporal.ChronoUnit;
113import java.time.temporal.JulianFields;
114import java.time.temporal.Temporal;
115import java.time.temporal.TemporalAccessor;
116import java.time.temporal.TemporalAdjuster;
117import java.time.temporal.TemporalAmount;
118import java.time.temporal.TemporalField;
119import java.time.temporal.TemporalQueries;
120import java.time.temporal.TemporalQuery;
121import java.time.temporal.TemporalUnit;
122import java.time.temporal.UnsupportedTemporalTypeException;
123import java.time.temporal.ValueRange;
124import java.util.ArrayList;
125import java.util.Arrays;
126import java.util.EnumSet;
127import java.util.Iterator;
128import java.util.List;
129
130import org.testng.annotations.BeforeMethod;
131import org.testng.annotations.DataProvider;
132import org.testng.annotations.Test;
133
134/**
135 * Test LocalTime.
136 */
137@Test
138public class TCKLocalTime extends AbstractDateTimeTest {
139
140    private static final ZoneOffset OFFSET_PTWO = ZoneOffset.ofHours(2);
141    private static final ZoneOffset OFFSET_MTWO = ZoneOffset.ofHours(-2);
142    private static final ZoneId ZONE_PARIS = ZoneId.of("Europe/Paris");
143
144    private LocalTime TEST_12_30_40_987654321;
145
146    private static final TemporalUnit[] INVALID_UNITS;
147    static {
148        EnumSet<ChronoUnit> set = EnumSet.range(DAYS, FOREVER);
149        INVALID_UNITS = set.toArray(new TemporalUnit[set.size()]);
150    }
151
152    @BeforeMethod
153    public void setUp() {
154        TEST_12_30_40_987654321 = LocalTime.of(12, 30, 40, 987654321);
155    }
156
157    //-----------------------------------------------------------------------
158    @Override
159    protected List<TemporalAccessor> samples() {
160        TemporalAccessor[] array = {TEST_12_30_40_987654321, LocalTime.MIN, LocalTime.MAX, LocalTime.MIDNIGHT, LocalTime.NOON};
161        return Arrays.asList(array);
162    }
163
164    @Override
165    protected List<TemporalField> validFields() {
166        TemporalField[] array = {
167            NANO_OF_SECOND,
168            NANO_OF_DAY,
169            MICRO_OF_SECOND,
170            MICRO_OF_DAY,
171            MILLI_OF_SECOND,
172            MILLI_OF_DAY,
173            SECOND_OF_MINUTE,
174            SECOND_OF_DAY,
175            MINUTE_OF_HOUR,
176            MINUTE_OF_DAY,
177            CLOCK_HOUR_OF_AMPM,
178            HOUR_OF_AMPM,
179            CLOCK_HOUR_OF_DAY,
180            HOUR_OF_DAY,
181            AMPM_OF_DAY,
182        };
183        return Arrays.asList(array);
184    }
185
186    @Override
187    protected List<TemporalField> invalidFields() {
188        List<TemporalField> list = new ArrayList<>(Arrays.<TemporalField>asList(ChronoField.values()));
189        list.removeAll(validFields());
190        list.add(JulianFields.JULIAN_DAY);
191        list.add(JulianFields.MODIFIED_JULIAN_DAY);
192        list.add(JulianFields.RATA_DIE);
193        return list;
194    }
195
196    //-----------------------------------------------------------------------
197
198    private void check(LocalTime test, int h, int m, int s, int n) {
199        assertEquals(test.getHour(), h);
200        assertEquals(test.getMinute(), m);
201        assertEquals(test.getSecond(), s);
202        assertEquals(test.getNano(), n);
203        assertEquals(test, test);
204        assertEquals(test.hashCode(), test.hashCode());
205        assertEquals(LocalTime.of(h, m, s, n), test);
206    }
207
208    //-----------------------------------------------------------------------
209    // constants
210    //-----------------------------------------------------------------------
211    @Test
212    public void constant_MIDNIGHT() {
213        check(LocalTime.MIDNIGHT, 0, 0, 0, 0);
214    }
215
216    @Test
217    public void constant_MIDDAY() {
218        check(LocalTime.NOON, 12, 0, 0, 0);
219    }
220
221    @Test
222    public void constant_MIN() {
223        check(LocalTime.MIN, 0, 0, 0, 0);
224    }
225
226    @Test
227    public void constant_MAX() {
228        check(LocalTime.MAX, 23, 59, 59, 999999999);
229    }
230
231    //-----------------------------------------------------------------------
232    // now(ZoneId)
233    //-----------------------------------------------------------------------
234    @Test(expectedExceptions=NullPointerException.class)
235    public void now_ZoneId_nullZoneId() {
236        LocalTime.now((ZoneId) null);
237    }
238
239    @Test
240    public void now_ZoneId() {
241        ZoneId zone = ZoneId.of("UTC+01:02:03");
242        LocalTime expected = LocalTime.now(Clock.system(zone));
243        LocalTime test = LocalTime.now(zone);
244        for (int i = 0; i < 100; i++) {
245            if (expected.equals(test)) {
246                return;
247            }
248            expected = LocalTime.now(Clock.system(zone));
249            test = LocalTime.now(zone);
250        }
251        assertEquals(test.truncatedTo(ChronoUnit.SECONDS),
252                     expected.truncatedTo(ChronoUnit.SECONDS));
253    }
254
255    //-----------------------------------------------------------------------
256    // now(Clock)
257    //-----------------------------------------------------------------------
258    @Test(expectedExceptions=NullPointerException.class)
259    public void now_Clock_nullClock() {
260        LocalTime.now((Clock) null);
261    }
262
263    @Test
264    public void now_Clock_allSecsInDay() {
265        for (int i = 0; i < (2 * 24 * 60 * 60); i++) {
266            Instant instant = Instant.ofEpochSecond(i, 8);
267            Clock clock = Clock.fixed(instant, ZoneOffset.UTC);
268            LocalTime test = LocalTime.now(clock);
269            assertEquals(test.getHour(), (i / (60 * 60)) % 24);
270            assertEquals(test.getMinute(), (i / 60) % 60);
271            assertEquals(test.getSecond(), i % 60);
272            assertEquals(test.getNano(), 8);
273        }
274    }
275
276    @Test
277    public void now_Clock_beforeEpoch() {
278        for (int i =-1; i >= -(24 * 60 * 60); i--) {
279            Instant instant = Instant.ofEpochSecond(i, 8);
280            Clock clock = Clock.fixed(instant, ZoneOffset.UTC);
281            LocalTime test = LocalTime.now(clock);
282            assertEquals(test.getHour(), ((i + 24 * 60 * 60) / (60 * 60)) % 24);
283            assertEquals(test.getMinute(), ((i + 24 * 60 * 60) / 60) % 60);
284            assertEquals(test.getSecond(), (i + 24 * 60 * 60) % 60);
285            assertEquals(test.getNano(), 8);
286        }
287    }
288
289    //-----------------------------------------------------------------------
290    @Test
291    public void now_Clock_max() {
292        Clock clock = Clock.fixed(Instant.MAX, ZoneOffset.UTC);
293        LocalTime test = LocalTime.now(clock);
294        assertEquals(test.getHour(), 23);
295        assertEquals(test.getMinute(), 59);
296        assertEquals(test.getSecond(), 59);
297        assertEquals(test.getNano(), 999_999_999);
298    }
299
300    @Test
301    public void now_Clock_min() {
302        Clock clock = Clock.fixed(Instant.MIN, ZoneOffset.UTC);
303        LocalTime test = LocalTime.now(clock);
304        assertEquals(test.getHour(), 0);
305        assertEquals(test.getMinute(), 0);
306        assertEquals(test.getSecond(), 0);
307        assertEquals(test.getNano(), 0);
308    }
309
310    //-----------------------------------------------------------------------
311    // of() factories
312    //-----------------------------------------------------------------------
313    @Test
314    public void factory_time_2ints() {
315        LocalTime test = LocalTime.of(12, 30);
316        check(test, 12, 30, 0, 0);
317    }
318
319    @Test(expectedExceptions=DateTimeException.class)
320    public void factory_time_2ints_hourTooLow() {
321        LocalTime.of(-1, 0);
322    }
323
324    @Test(expectedExceptions=DateTimeException.class)
325    public void factory_time_2ints_hourTooHigh() {
326        LocalTime.of(24, 0);
327    }
328
329    @Test(expectedExceptions=DateTimeException.class)
330    public void factory_time_2ints_minuteTooLow() {
331        LocalTime.of(0, -1);
332    }
333
334    @Test(expectedExceptions=DateTimeException.class)
335    public void factory_time_2ints_minuteTooHigh() {
336        LocalTime.of(0, 60);
337    }
338
339    //-----------------------------------------------------------------------
340    @Test
341    public void factory_time_3ints() {
342        LocalTime test = LocalTime.of(12, 30, 40);
343        check(test, 12, 30, 40, 0);
344    }
345
346    @Test(expectedExceptions=DateTimeException.class)
347    public void factory_time_3ints_hourTooLow() {
348        LocalTime.of(-1, 0, 0);
349    }
350
351    @Test(expectedExceptions=DateTimeException.class)
352    public void factory_time_3ints_hourTooHigh() {
353        LocalTime.of(24, 0, 0);
354    }
355
356    @Test(expectedExceptions=DateTimeException.class)
357    public void factory_time_3ints_minuteTooLow() {
358        LocalTime.of(0, -1, 0);
359    }
360
361    @Test(expectedExceptions=DateTimeException.class)
362    public void factory_time_3ints_minuteTooHigh() {
363        LocalTime.of(0, 60, 0);
364    }
365
366    @Test(expectedExceptions=DateTimeException.class)
367    public void factory_time_3ints_secondTooLow() {
368        LocalTime.of(0, 0, -1);
369    }
370
371    @Test(expectedExceptions=DateTimeException.class)
372    public void factory_time_3ints_secondTooHigh() {
373        LocalTime.of(0, 0, 60);
374    }
375
376    //-----------------------------------------------------------------------
377    @Test
378    public void factory_time_4ints() {
379        LocalTime test = LocalTime.of(12, 30, 40, 987654321);
380        check(test, 12, 30, 40, 987654321);
381        test = LocalTime.of(12, 0, 40, 987654321);
382        check(test, 12, 0, 40, 987654321);
383    }
384
385    @Test(expectedExceptions=DateTimeException.class)
386    public void factory_time_4ints_hourTooLow() {
387        LocalTime.of(-1, 0, 0, 0);
388    }
389
390    @Test(expectedExceptions=DateTimeException.class)
391    public void factory_time_4ints_hourTooHigh() {
392        LocalTime.of(24, 0, 0, 0);
393    }
394
395    @Test(expectedExceptions=DateTimeException.class)
396    public void factory_time_4ints_minuteTooLow() {
397        LocalTime.of(0, -1, 0, 0);
398    }
399
400    @Test(expectedExceptions=DateTimeException.class)
401    public void factory_time_4ints_minuteTooHigh() {
402        LocalTime.of(0, 60, 0, 0);
403    }
404
405    @Test(expectedExceptions=DateTimeException.class)
406    public void factory_time_4ints_secondTooLow() {
407        LocalTime.of(0, 0, -1, 0);
408    }
409
410    @Test(expectedExceptions=DateTimeException.class)
411    public void factory_time_4ints_secondTooHigh() {
412        LocalTime.of(0, 0, 60, 0);
413    }
414
415    @Test(expectedExceptions=DateTimeException.class)
416    public void factory_time_4ints_nanoTooLow() {
417        LocalTime.of(0, 0, 0, -1);
418    }
419
420    @Test(expectedExceptions=DateTimeException.class)
421    public void factory_time_4ints_nanoTooHigh() {
422        LocalTime.of(0, 0, 0, 1000000000);
423    }
424
425     //-----------------------------------------------------------------------
426     // ofInstant()
427     //-----------------------------------------------------------------------
428     @DataProvider(name="instantFactory")
429     Object[][] data_instantFactory() {
430         return new Object[][] {
431                 {Instant.ofEpochSecond(86400 + 3600 + 120 + 4, 500), ZONE_PARIS, LocalTime.of(2, 2, 4, 500)},
432                 {Instant.ofEpochSecond(86400 + 3600 + 120 + 4, 500), OFFSET_MTWO, LocalTime.of(23, 2, 4, 500)},
433                 {Instant.ofEpochSecond(-86400 + 4, 500), OFFSET_PTWO, LocalTime.of(2, 0, 4, 500)},
434                 {OffsetDateTime.of(LocalDateTime.of(Year.MIN_VALUE, 1, 1, 0, 0), ZoneOffset.UTC).toInstant(),
435                         ZoneOffset.UTC, LocalTime.MIN},
436                 {OffsetDateTime.of(LocalDateTime.of(Year.MAX_VALUE, 12, 31, 23, 59, 59, 999_999_999), ZoneOffset.UTC).toInstant(),
437                         ZoneOffset.UTC, LocalTime.MAX},
438         };
439     }
440
441     @Test(dataProvider="instantFactory")
442     public void factory_ofInstant(Instant instant, ZoneId zone, LocalTime expected) {
443         LocalTime test = LocalTime.ofInstant(instant, zone);
444         assertEquals(test, expected);
445     }
446
447     @Test(expectedExceptions=NullPointerException.class)
448     public void factory_ofInstant_nullInstant() {
449         LocalTime.ofInstant((Instant) null, ZONE_PARIS);
450     }
451
452     @Test(expectedExceptions=NullPointerException.class)
453     public void factory_ofInstant_nullZone() {
454         LocalTime.ofInstant(Instant.EPOCH, (ZoneId) null);
455     }
456
457    //-----------------------------------------------------------------------
458    // ofSecondOfDay(long)
459    //-----------------------------------------------------------------------
460    @Test
461    public void factory_ofSecondOfDay() {
462        LocalTime localTime = LocalTime.ofSecondOfDay(2 * 60 * 60 + 17 * 60 + 23);
463        check(localTime, 2, 17, 23, 0);
464    }
465
466    @Test(expectedExceptions=DateTimeException.class)
467    public void factory_ofSecondOfDay_tooLow() {
468        LocalTime.ofSecondOfDay(-1);
469    }
470
471    @Test(expectedExceptions=DateTimeException.class)
472    public void factory_ofSecondOfDay_tooHigh() {
473        LocalTime.ofSecondOfDay(24 * 60 * 60);
474    }
475
476    //-----------------------------------------------------------------------
477    // ofNanoOfDay(long)
478    //-----------------------------------------------------------------------
479    @Test
480    public void factory_ofNanoOfDay() {
481        LocalTime localTime = LocalTime.ofNanoOfDay(60 * 60 * 1000000000L + 17);
482        check(localTime, 1, 0, 0, 17);
483    }
484
485    @Test(expectedExceptions=DateTimeException.class)
486    public void factory_ofNanoOfDay_tooLow() {
487        LocalTime.ofNanoOfDay(-1);
488    }
489
490    @Test(expectedExceptions=DateTimeException.class)
491    public void factory_ofNanoOfDay_tooHigh() {
492        LocalTime.ofNanoOfDay(24 * 60 * 60 * 1000000000L);
493    }
494
495    //-----------------------------------------------------------------------
496    // from()
497    //-----------------------------------------------------------------------
498    @Test
499    public void factory_from_TemporalAccessor() {
500        assertEquals(LocalTime.from(LocalTime.of(17, 30)), LocalTime.of(17, 30));
501        assertEquals(LocalTime.from(LocalDateTime.of(2012, 5, 1, 17, 30)), LocalTime.of(17, 30));
502    }
503
504    @Test(expectedExceptions=DateTimeException.class)
505    public void factory_from_TemporalAccessor_invalid_noDerive() {
506        LocalTime.from(LocalDate.of(2007, 7, 15));
507    }
508
509    @Test(expectedExceptions=NullPointerException.class)
510    public void factory_from_TemporalAccessor_null() {
511        LocalTime.from((TemporalAccessor) null);
512    }
513
514    //-----------------------------------------------------------------------
515    // parse()
516    //-----------------------------------------------------------------------
517    @Test(dataProvider = "sampleToString")
518    public void factory_parse_validText(int h, int m, int s, int n, String parsable) {
519        LocalTime t = LocalTime.parse(parsable);
520        assertNotNull(t, parsable);
521        assertEquals(t.getHour(), h);
522        assertEquals(t.getMinute(), m);
523        assertEquals(t.getSecond(), s);
524        assertEquals(t.getNano(), n);
525    }
526
527    @DataProvider(name="sampleBadParse")
528    Object[][] provider_sampleBadParse() {
529        return new Object[][]{
530                {"00;00"},
531                {"12-00"},
532                {"-01:00"},
533                {"00:00:00-09"},
534                {"00:00:00,09"},
535                {"00:00:abs"},
536                {"11"},
537                {"11:30+01:00"},
538                {"11:30+01:00[Europe/Paris]"},
539        };
540    }
541
542    @Test(dataProvider = "sampleBadParse", expectedExceptions={DateTimeParseException.class})
543    public void factory_parse_invalidText(String unparsable) {
544        LocalTime.parse(unparsable);
545    }
546
547    //-----------------------------------------------------------------------s
548    @Test(expectedExceptions=DateTimeParseException.class)
549    public void factory_parse_illegalHour() {
550        LocalTime.parse("25:00");
551    }
552
553    @Test(expectedExceptions=DateTimeParseException.class)
554    public void factory_parse_illegalMinute() {
555        LocalTime.parse("12:60");
556    }
557
558    @Test(expectedExceptions=DateTimeParseException.class)
559    public void factory_parse_illegalSecond() {
560        LocalTime.parse("12:12:60");
561    }
562
563    //-----------------------------------------------------------------------s
564    @Test(expectedExceptions = {NullPointerException.class})
565    public void factory_parse_nullTest() {
566        LocalTime.parse((String) null);
567    }
568
569    //-----------------------------------------------------------------------
570    // parse(DateTimeFormatter)
571    //-----------------------------------------------------------------------
572    @Test
573    public void factory_parse_formatter() {
574        DateTimeFormatter f = DateTimeFormatter.ofPattern("H m s");
575        LocalTime test = LocalTime.parse("14 30 40", f);
576        assertEquals(test, LocalTime.of(14, 30, 40));
577    }
578
579    @Test(expectedExceptions=NullPointerException.class)
580    public void factory_parse_formatter_nullText() {
581        DateTimeFormatter f = DateTimeFormatter.ofPattern("H m s");
582        LocalTime.parse((String) null, f);
583    }
584
585    @Test(expectedExceptions=NullPointerException.class)
586    public void factory_parse_formatter_nullFormatter() {
587        LocalTime.parse("ANY", null);
588    }
589
590    //-----------------------------------------------------------------------
591    // isSupported(TemporalField)
592    //-----------------------------------------------------------------------
593    @Test
594    public void test_isSupported_TemporalField() {
595        assertEquals(TEST_12_30_40_987654321.isSupported((TemporalField) null), false);
596        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.NANO_OF_SECOND), true);
597        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.NANO_OF_DAY), true);
598        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.MICRO_OF_SECOND), true);
599        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.MICRO_OF_DAY), true);
600        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.MILLI_OF_SECOND), true);
601        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.MILLI_OF_DAY), true);
602        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.SECOND_OF_MINUTE), true);
603        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.SECOND_OF_DAY), true);
604        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.MINUTE_OF_HOUR), true);
605        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.MINUTE_OF_DAY), true);
606        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.HOUR_OF_AMPM), true);
607        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.CLOCK_HOUR_OF_AMPM), true);
608        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.HOUR_OF_DAY), true);
609        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.CLOCK_HOUR_OF_DAY), true);
610        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.AMPM_OF_DAY), true);
611        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.DAY_OF_WEEK), false);
612        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), false);
613        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR), false);
614        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.DAY_OF_MONTH), false);
615        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.DAY_OF_YEAR), false);
616        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.EPOCH_DAY), false);
617        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.ALIGNED_WEEK_OF_MONTH), false);
618        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.ALIGNED_WEEK_OF_YEAR), false);
619        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.MONTH_OF_YEAR), false);
620        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.PROLEPTIC_MONTH), false);
621        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.YEAR), false);
622        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.YEAR_OF_ERA), false);
623        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.ERA), false);
624        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.INSTANT_SECONDS), false);
625        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.OFFSET_SECONDS), false);
626    }
627
628    //-----------------------------------------------------------------------
629    // isSupported(TemporalUnit)
630    //-----------------------------------------------------------------------
631    @Test
632    public void test_isSupported_TemporalUnit() {
633        assertEquals(TEST_12_30_40_987654321.isSupported((TemporalUnit) null), false);
634        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.NANOS), true);
635        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.MICROS), true);
636        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.MILLIS), true);
637        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.SECONDS), true);
638        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.MINUTES), true);
639        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.HOURS), true);
640        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.HALF_DAYS), true);
641        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.DAYS), false);
642        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.WEEKS), false);
643        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.MONTHS), false);
644        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.YEARS), false);
645        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.DECADES), false);
646        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.CENTURIES), false);
647        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.MILLENNIA), false);
648        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.ERAS), false);
649        assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.FOREVER), false);
650    }
651
652    //-----------------------------------------------------------------------
653    // get(TemporalField)
654    //-----------------------------------------------------------------------
655    @Test
656    public void test_get_TemporalField() {
657        LocalTime test = TEST_12_30_40_987654321;
658        assertEquals(test.get(ChronoField.HOUR_OF_DAY), 12);
659        assertEquals(test.get(ChronoField.MINUTE_OF_HOUR), 30);
660        assertEquals(test.get(ChronoField.SECOND_OF_MINUTE), 40);
661        assertEquals(test.get(ChronoField.NANO_OF_SECOND), 987654321);
662
663        assertEquals(test.get(ChronoField.SECOND_OF_DAY), 12 * 3600 + 30 * 60 + 40);
664        assertEquals(test.get(ChronoField.MINUTE_OF_DAY), 12 * 60 + 30);
665        assertEquals(test.get(ChronoField.HOUR_OF_AMPM), 0);
666        assertEquals(test.get(ChronoField.CLOCK_HOUR_OF_AMPM), 12);
667        assertEquals(test.get(ChronoField.CLOCK_HOUR_OF_DAY), 12);
668        assertEquals(test.get(ChronoField.AMPM_OF_DAY), 1);
669    }
670
671    @Test
672    public void test_getLong_TemporalField() {
673        LocalTime test = TEST_12_30_40_987654321;
674        assertEquals(test.getLong(ChronoField.HOUR_OF_DAY), 12);
675        assertEquals(test.getLong(ChronoField.MINUTE_OF_HOUR), 30);
676        assertEquals(test.getLong(ChronoField.SECOND_OF_MINUTE), 40);
677        assertEquals(test.getLong(ChronoField.NANO_OF_SECOND), 987654321);
678
679        assertEquals(test.getLong(ChronoField.SECOND_OF_DAY), 12 * 3600 + 30 * 60 + 40);
680        assertEquals(test.getLong(ChronoField.MINUTE_OF_DAY), 12 * 60 + 30);
681        assertEquals(test.getLong(ChronoField.HOUR_OF_AMPM), 0);
682        assertEquals(test.getLong(ChronoField.CLOCK_HOUR_OF_AMPM), 12);
683        assertEquals(test.getLong(ChronoField.CLOCK_HOUR_OF_DAY), 12);
684        assertEquals(test.getLong(ChronoField.AMPM_OF_DAY), 1);
685    }
686
687    //-----------------------------------------------------------------------
688    // query(TemporalQuery)
689    //-----------------------------------------------------------------------
690    @DataProvider(name="query")
691    Object[][] data_query() {
692        return new Object[][] {
693                {TEST_12_30_40_987654321, TemporalQueries.chronology(), null},
694                {TEST_12_30_40_987654321, TemporalQueries.zoneId(), null},
695                {TEST_12_30_40_987654321, TemporalQueries.precision(), ChronoUnit.NANOS},
696                {TEST_12_30_40_987654321, TemporalQueries.zone(), null},
697                {TEST_12_30_40_987654321, TemporalQueries.offset(), null},
698                {TEST_12_30_40_987654321, TemporalQueries.localDate(), null},
699                {TEST_12_30_40_987654321, TemporalQueries.localTime(), TEST_12_30_40_987654321},
700        };
701    }
702
703    @Test(dataProvider="query")
704    public <T> void test_query(TemporalAccessor temporal, TemporalQuery<T> query, T expected) {
705        assertEquals(temporal.query(query), expected);
706    }
707
708    @Test(dataProvider="query")
709    public <T> void test_queryFrom(TemporalAccessor temporal, TemporalQuery<T> query, T expected) {
710        assertEquals(query.queryFrom(temporal), expected);
711    }
712
713    @Test(expectedExceptions=NullPointerException.class)
714    public void test_query_null() {
715        TEST_12_30_40_987654321.query(null);
716    }
717
718    //-----------------------------------------------------------------------
719    // get*()
720    //-----------------------------------------------------------------------
721    @DataProvider(name="sampleTimes")
722    Object[][] provider_sampleTimes() {
723        return new Object[][] {
724            {0, 0, 0, 0},
725            {0, 0, 0, 1},
726            {0, 0, 1, 0},
727            {0, 0, 1, 1},
728            {0, 1, 0, 0},
729            {0, 1, 0, 1},
730            {0, 1, 1, 0},
731            {0, 1, 1, 1},
732            {1, 0, 0, 0},
733            {1, 0, 0, 1},
734            {1, 0, 1, 0},
735            {1, 0, 1, 1},
736            {1, 1, 0, 0},
737            {1, 1, 0, 1},
738            {1, 1, 1, 0},
739            {1, 1, 1, 1},
740        };
741    }
742
743    //-----------------------------------------------------------------------
744    @Test(dataProvider="sampleTimes")
745    public void test_get(int h, int m, int s, int ns) {
746        LocalTime a = LocalTime.of(h, m, s, ns);
747        assertEquals(a.getHour(), h);
748        assertEquals(a.getMinute(), m);
749        assertEquals(a.getSecond(), s);
750        assertEquals(a.getNano(), ns);
751    }
752
753    //-----------------------------------------------------------------------
754    // adjustInto(Temporal)
755    //-----------------------------------------------------------------------
756    @DataProvider(name="adjustInto")
757    Object[][] data_adjustInto() {
758        return new Object[][]{
759                {LocalTime.of(23, 5), LocalTime.of(4, 1, 1, 100), LocalTime.of(23, 5, 0, 0), null},
760                {LocalTime.of(23, 5, 20), LocalTime.of(4, 1, 1, 100), LocalTime.of(23, 5, 20, 0), null},
761                {LocalTime.of(23, 5, 20, 1000), LocalTime.of(4, 1, 1, 100), LocalTime.of(23, 5, 20, 1000), null},
762                {LocalTime.of(23, 5, 20, 1000), LocalTime.MAX, LocalTime.of(23, 5, 20, 1000), null},
763                {LocalTime.of(23, 5, 20, 1000), LocalTime.MIN, LocalTime.of(23, 5, 20, 1000), null},
764                {LocalTime.of(23, 5, 20, 1000), LocalTime.NOON, LocalTime.of(23, 5, 20, 1000), null},
765                {LocalTime.of(23, 5, 20, 1000), LocalTime.MIDNIGHT, LocalTime.of(23, 5, 20, 1000), null},
766                {LocalTime.MAX, LocalTime.of(23, 5, 20, 1000), LocalTime.of(23, 59, 59, 999999999), null},
767                {LocalTime.MIN, LocalTime.of(23, 5, 20, 1000), LocalTime.of(0, 0, 0), null},
768                {LocalTime.NOON, LocalTime.of(23, 5, 20, 1000), LocalTime.of(12, 0, 0), null},
769                {LocalTime.MIDNIGHT, LocalTime.of(23, 5, 20, 1000), LocalTime.of(0, 0, 0), null},
770
771                {LocalTime.of(23, 5), LocalDateTime.of(2210, 2, 2, 1, 1), LocalDateTime.of(2210, 2, 2, 23, 5), null},
772                {LocalTime.of(23, 5), OffsetTime.of(1, 1, 0, 0, OFFSET_PTWO), OffsetTime.of(23, 5, 0, 0, OFFSET_PTWO), null},
773                {LocalTime.of(23, 5), OffsetDateTime.of(2210, 2, 2, 1, 1, 0, 0, OFFSET_PTWO), OffsetDateTime.of(2210, 2, 2, 23, 5, 0, 0, OFFSET_PTWO), null},
774                {LocalTime.of(23, 5), ZonedDateTime.of(2210, 2, 2, 1, 1, 0, 0, ZONE_PARIS), ZonedDateTime.of(2210, 2, 2, 23, 5, 0, 0, ZONE_PARIS), null},
775
776                {LocalTime.of(23, 5), LocalDate.of(2210, 2, 2), null, DateTimeException.class},
777                {LocalTime.of(23, 5), null, null, NullPointerException.class},
778
779        };
780    }
781
782    @Test(dataProvider="adjustInto")
783    public void test_adjustInto(LocalTime test, Temporal temporal, Temporal expected, Class<?> expectedEx) {
784        if (expectedEx == null) {
785            Temporal result = test.adjustInto(temporal);
786            assertEquals(result, expected);
787        } else {
788            try {
789                Temporal result = test.adjustInto(temporal);
790                fail();
791            } catch (Exception ex) {
792                assertTrue(expectedEx.isInstance(ex));
793            }
794        }
795    }
796
797    //-----------------------------------------------------------------------
798    // with(TemporalAdjuster)
799    //-----------------------------------------------------------------------
800    @Test
801    public void test_with_adjustment() {
802        final LocalTime sample = LocalTime.of(23, 5);
803        TemporalAdjuster adjuster = new TemporalAdjuster() {
804            @Override
805            public Temporal adjustInto(Temporal dateTime) {
806                return sample;
807            }
808        };
809        assertEquals(TEST_12_30_40_987654321.with(adjuster), sample);
810    }
811
812    @Test(expectedExceptions=NullPointerException.class)
813    public void test_with_adjustment_null() {
814        TEST_12_30_40_987654321.with((TemporalAdjuster) null);
815    }
816
817    //-----------------------------------------------------------------------
818    // with(TemporalField, long)
819    //-----------------------------------------------------------------------
820    private long[] testPoints(long max) {
821        long[] points = new long[9];
822        points[0] = 0;
823        points[1] = 1;
824        points[2] = 2;
825        points[3] = max / 7;
826        points[4] = (max / 7) * 2;
827        points[5] = (max / 2);
828        points[6] = (max / 7) * 6;;
829        points[7] = max - 2;
830        points[8] = max - 1;
831        return points;
832    }
833
834    // Returns a {@code LocalTime} with the specified nano-of-second.
835    // The hour, minute and second will be unchanged.
836    @Test
837    public void test_with_longTemporalField_nanoOfSecond() {
838        for (long i : testPoints(1_000_000_000L)) {
839            LocalTime test = TEST_12_30_40_987654321.with(NANO_OF_SECOND, i);
840            assertEquals(test.get(NANO_OF_SECOND),  i);
841            assertEquals(test.get(HOUR_OF_DAY), TEST_12_30_40_987654321.get(HOUR_OF_DAY));
842            assertEquals(test.get(MINUTE_OF_HOUR), TEST_12_30_40_987654321.get(MINUTE_OF_HOUR));
843            assertEquals(test.get(SECOND_OF_MINUTE), TEST_12_30_40_987654321.get(SECOND_OF_MINUTE));
844        }
845    }
846
847    // Returns a {@code LocalTime} with the specified nano-of-day.
848    // This completely replaces the time and is equivalent to {@link #ofNanoOfDay(long)}.
849    @Test
850    public void test_with_longTemporalField_nanoOfDay() {
851        for (long i : testPoints(86_400_000_000_000L)) {
852            LocalTime test = TEST_12_30_40_987654321.with(NANO_OF_DAY, i);
853            assertEquals(test, LocalTime.ofNanoOfDay(i));
854        }
855    }
856
857    // Returns a {@code LocalTime} with the nano-of-second replaced by the specified
858    // micro-of-second multiplied by 1,000.
859    // The hour, minute and second will be unchanged.
860    @Test
861    public void test_with_longTemporalField_microOfSecond() {
862        for (long i : testPoints(1_000_000L)) {
863            LocalTime test = TEST_12_30_40_987654321.with(MICRO_OF_SECOND, i);
864            assertEquals(test.get(NANO_OF_SECOND),  i * 1_000);
865            assertEquals(test.get(HOUR_OF_DAY), TEST_12_30_40_987654321.get(HOUR_OF_DAY));
866            assertEquals(test.get(MINUTE_OF_HOUR), TEST_12_30_40_987654321.get(MINUTE_OF_HOUR));
867            assertEquals(test.get(SECOND_OF_MINUTE), TEST_12_30_40_987654321.get(SECOND_OF_MINUTE));
868        }
869    }
870
871    // Returns a {@code LocalTime} with the specified micro-of-day.
872    // This completely replaces the time and is equivalent to using {@link #ofNanoOfDay(long)}
873    // with the micro-of-day multiplied by 1,000.
874    @Test
875    public void test_with_longTemporalField_microOfDay() {
876        for (long i : testPoints(86_400_000_000L)) {
877            LocalTime test = TEST_12_30_40_987654321.with(MICRO_OF_DAY, i);
878            assertEquals(test, LocalTime.ofNanoOfDay(i * 1000));
879        }
880    }
881
882    // Returns a {@code LocalTime} with the nano-of-second replaced by the specified
883    // milli-of-second multiplied by 1,000,000.
884    // The hour, minute and second will be unchanged.
885    @Test
886    public void test_with_longTemporalField_milliOfSecond() {
887        for (long i : testPoints(1_000L)) {
888            LocalTime test = TEST_12_30_40_987654321.with(MILLI_OF_SECOND, i);
889            assertEquals(test.get(NANO_OF_SECOND),  i * 1_000_000);
890            assertEquals(test.get(HOUR_OF_DAY), TEST_12_30_40_987654321.get(HOUR_OF_DAY));
891            assertEquals(test.get(MINUTE_OF_HOUR), TEST_12_30_40_987654321.get(MINUTE_OF_HOUR));
892            assertEquals(test.get(SECOND_OF_MINUTE), TEST_12_30_40_987654321.get(SECOND_OF_MINUTE));
893        }
894    }
895
896    // Returns a {@code LocalTime} with the specified milli-of-day.
897    // This completely replaces the time and is equivalent to using {@link #ofNanoOfDay(long)}
898    // with the milli-of-day multiplied by 1,000,000.
899    @Test
900    public void test_with_longTemporalField_milliOfDay() {
901        for (long i : testPoints(86_400_000L)) {
902            LocalTime test = TEST_12_30_40_987654321.with(MILLI_OF_DAY, i);
903            assertEquals(test, LocalTime.ofNanoOfDay(i * 1_000_000));
904        }
905    }
906
907    // Returns a {@code LocalTime} with the specified second-of-minute.
908    // The hour, minute and nano-of-second will be unchanged.
909    @Test
910    public void test_with_longTemporalField_secondOfMinute() {
911        for (long i : testPoints(60L)) {
912            LocalTime test = TEST_12_30_40_987654321.with(SECOND_OF_MINUTE, i);
913            assertEquals(test.get(SECOND_OF_MINUTE), i);
914            assertEquals(test.get(HOUR_OF_DAY), TEST_12_30_40_987654321.get(HOUR_OF_DAY));
915            assertEquals(test.get(MINUTE_OF_HOUR), TEST_12_30_40_987654321.get(MINUTE_OF_HOUR));
916            assertEquals(test.get(NANO_OF_SECOND), TEST_12_30_40_987654321.get(NANO_OF_SECOND));
917        }
918    }
919
920    // Returns a {@code LocalTime} with the specified second-of-day.
921    // The nano-of-second will be unchanged.
922    @Test
923    public void test_with_longTemporalField_secondOfDay() {
924        for (long i : testPoints(24 * 60 * 60)) {
925            LocalTime test = TEST_12_30_40_987654321.with(SECOND_OF_DAY, i);
926            assertEquals(test.get(SECOND_OF_DAY), i);
927            assertEquals(test.get(NANO_OF_SECOND), TEST_12_30_40_987654321.get(NANO_OF_SECOND));
928        }
929    }
930
931    // Returns a {@code LocalTime} with the specified minute-of-hour.
932    // The hour, second-of-minute and nano-of-second will be unchanged.
933    @Test
934    public void test_with_longTemporalField_minuteOfHour() {
935        for (long i : testPoints(60)) {
936            LocalTime test = TEST_12_30_40_987654321.with(MINUTE_OF_HOUR, i);
937            assertEquals(test.get(MINUTE_OF_HOUR), i);
938            assertEquals(test.get(HOUR_OF_DAY), TEST_12_30_40_987654321.get(HOUR_OF_DAY));
939            assertEquals(test.get(SECOND_OF_MINUTE), TEST_12_30_40_987654321.get(SECOND_OF_MINUTE));
940            assertEquals(test.get(NANO_OF_SECOND), TEST_12_30_40_987654321.get(NANO_OF_SECOND));
941        }
942    }
943
944    // Returns a {@code LocalTime} with the specified minute-of-day.
945    // The second-of-minute and nano-of-second will be unchanged.
946    @Test
947    public void test_with_longTemporalField_minuteOfDay() {
948        for (long i : testPoints(24 * 60)) {
949            LocalTime test = TEST_12_30_40_987654321.with(MINUTE_OF_DAY, i);
950            assertEquals(test.get(MINUTE_OF_DAY), i);
951            assertEquals(test.get(SECOND_OF_MINUTE), TEST_12_30_40_987654321.get(SECOND_OF_MINUTE));
952            assertEquals(test.get(NANO_OF_SECOND), TEST_12_30_40_987654321.get(NANO_OF_SECOND));
953        }
954    }
955
956    // Returns a {@code LocalTime} with the specified hour-of-am-pm.
957    // The AM/PM, minute-of-hour, second-of-minute and nano-of-second will be unchanged.
958    @Test
959    public void test_with_longTemporalField_hourOfAmPm() {
960        for (int i = 0; i < 12; i++) {
961            LocalTime test = TEST_12_30_40_987654321.with(HOUR_OF_AMPM, i);
962            assertEquals(test.get(HOUR_OF_AMPM), i);
963            assertEquals(test.get(AMPM_OF_DAY), TEST_12_30_40_987654321.get(AMPM_OF_DAY));
964            assertEquals(test.get(MINUTE_OF_HOUR), TEST_12_30_40_987654321.get(MINUTE_OF_HOUR));
965            assertEquals(test.get(SECOND_OF_MINUTE), TEST_12_30_40_987654321.get(SECOND_OF_MINUTE));
966            assertEquals(test.get(NANO_OF_SECOND), TEST_12_30_40_987654321.get(NANO_OF_SECOND));
967        }
968    }
969
970    // Returns a {@code LocalTime} with the specified clock-hour-of-am-pm.
971    // The AM/PM, minute-of-hour, second-of-minute and nano-of-second will be unchanged.
972    @Test
973    public void test_with_longTemporalField_clockHourOfAmPm() {
974        for (int i = 1; i <= 12; i++) {
975            LocalTime test = TEST_12_30_40_987654321.with(CLOCK_HOUR_OF_AMPM, i);
976            assertEquals(test.get(CLOCK_HOUR_OF_AMPM), i);
977            assertEquals(test.get(AMPM_OF_DAY), TEST_12_30_40_987654321.get(AMPM_OF_DAY));
978            assertEquals(test.get(MINUTE_OF_HOUR), TEST_12_30_40_987654321.get(MINUTE_OF_HOUR));
979            assertEquals(test.get(SECOND_OF_MINUTE), TEST_12_30_40_987654321.get(SECOND_OF_MINUTE));
980            assertEquals(test.get(NANO_OF_SECOND), TEST_12_30_40_987654321.get(NANO_OF_SECOND));
981        }
982    }
983
984    // Returns a {@code LocalTime} with the specified hour-of-day.
985    // The minute-of-hour, second-of-minute and nano-of-second will be unchanged.
986    @Test
987    public void test_with_longTemporalField_hourOfDay() {
988        for (int i = 0; i < 24; i++) {
989            LocalTime test = TEST_12_30_40_987654321.with(HOUR_OF_DAY, i);
990            assertEquals(test.get(HOUR_OF_DAY), i);
991            assertEquals(test.get(MINUTE_OF_HOUR), TEST_12_30_40_987654321.get(MINUTE_OF_HOUR));
992            assertEquals(test.get(SECOND_OF_MINUTE), TEST_12_30_40_987654321.get(SECOND_OF_MINUTE));
993            assertEquals(test.get(NANO_OF_SECOND), TEST_12_30_40_987654321.get(NANO_OF_SECOND));
994        }
995    }
996
997    // Returns a {@code LocalTime} with the specified clock-hour-of-day.
998    // The minute-of-hour, second-of-minute and nano-of-second will be unchanged.
999    @Test
1000    public void test_with_longTemporalField_clockHourOfDay() {
1001        for (int i = 1; i <= 24; i++) {
1002            LocalTime test = TEST_12_30_40_987654321.with(CLOCK_HOUR_OF_DAY, i);
1003            assertEquals(test.get(CLOCK_HOUR_OF_DAY), i);
1004            assertEquals(test.get(MINUTE_OF_HOUR), TEST_12_30_40_987654321.get(MINUTE_OF_HOUR));
1005            assertEquals(test.get(SECOND_OF_MINUTE), TEST_12_30_40_987654321.get(SECOND_OF_MINUTE));
1006            assertEquals(test.get(NANO_OF_SECOND), TEST_12_30_40_987654321.get(NANO_OF_SECOND));
1007        }
1008    }
1009
1010    // Returns a {@code LocalTime} with the specified AM/PM.
1011    // The hour-of-am-pm, minute-of-hour, second-of-minute and nano-of-second will be unchanged.
1012    @Test
1013    public void test_with_longTemporalField_amPmOfDay() {
1014        for (int i = 0; i <= 1; i++) {
1015            LocalTime test = TEST_12_30_40_987654321.with(AMPM_OF_DAY, i);
1016            assertEquals(test.get(AMPM_OF_DAY), i);
1017            assertEquals(test.get(HOUR_OF_AMPM), TEST_12_30_40_987654321.get(HOUR_OF_AMPM));
1018            assertEquals(test.get(MINUTE_OF_HOUR), TEST_12_30_40_987654321.get(MINUTE_OF_HOUR));
1019            assertEquals(test.get(SECOND_OF_MINUTE), TEST_12_30_40_987654321.get(SECOND_OF_MINUTE));
1020            assertEquals(test.get(NANO_OF_SECOND), TEST_12_30_40_987654321.get(NANO_OF_SECOND));
1021        }
1022    }
1023
1024    // The supported fields behave as follows...
1025    // In all cases, if the new value is outside the valid range of values for the field
1026    // then a {@code DateTimeException} will be thrown.
1027    @DataProvider(name = "withTemporalField_outOfRange")
1028    Object[][] data_withTemporalField_outOfRange() {
1029        return new Object[][] {
1030                {NANO_OF_SECOND, time(0, 0, 0, 0), NANO_OF_SECOND.range().getMinimum() - 1},
1031                {NANO_OF_SECOND, time(0, 0, 0, 0), NANO_OF_SECOND.range().getMaximum() + 1},
1032
1033                {NANO_OF_DAY, time(0, 0, 0, 0), NANO_OF_DAY.range().getMinimum() - 1},
1034                {NANO_OF_DAY, time(0, 0, 0, 0), NANO_OF_DAY.range().getMaximum() + 1},
1035
1036                {MICRO_OF_SECOND, time(0, 0, 0, 0), MICRO_OF_SECOND.range().getMinimum() - 1},
1037                {MICRO_OF_SECOND, time(0, 0, 0, 0), MICRO_OF_SECOND.range().getMaximum() + 1},
1038
1039                {MICRO_OF_DAY, time(0, 0, 0, 0), MICRO_OF_DAY.range().getMinimum() - 1},
1040                {MICRO_OF_DAY, time(0, 0, 0, 0), MICRO_OF_DAY.range().getMaximum() + 1},
1041
1042                {MILLI_OF_SECOND, time(0, 0, 0, 0), MILLI_OF_SECOND.range().getMinimum() - 1},
1043                {MILLI_OF_SECOND, time(0, 0, 0, 0), MILLI_OF_SECOND.range().getMaximum() + 1},
1044
1045                {MILLI_OF_DAY, time(0, 0, 0, 0), MILLI_OF_DAY.range().getMinimum() - 1},
1046                {MILLI_OF_DAY, time(0, 0, 0, 0), MILLI_OF_DAY.range().getMaximum() + 1},
1047
1048                {SECOND_OF_MINUTE, time(0, 0, 0, 0), SECOND_OF_MINUTE.range().getMinimum() - 1},
1049                {SECOND_OF_MINUTE, time(0, 0, 0, 0), SECOND_OF_MINUTE.range().getMaximum() + 1},
1050
1051                {SECOND_OF_DAY, time(0, 0, 0, 0), SECOND_OF_DAY.range().getMinimum() - 1},
1052                {SECOND_OF_DAY, time(0, 0, 0, 0), SECOND_OF_DAY.range().getMaximum() + 1},
1053
1054                {MINUTE_OF_HOUR, time(0, 0, 0, 0), MINUTE_OF_HOUR.range().getMinimum() - 1},
1055                {MINUTE_OF_HOUR, time(0, 0, 0, 0), MINUTE_OF_HOUR.range().getMaximum() + 1},
1056
1057                {MINUTE_OF_DAY, time(0, 0, 0, 0), MINUTE_OF_DAY.range().getMinimum() - 1},
1058                {MINUTE_OF_DAY, time(0, 0, 0, 0), MINUTE_OF_DAY.range().getMaximum() + 1},
1059
1060                {HOUR_OF_AMPM, time(0, 0, 0, 0), HOUR_OF_AMPM.range().getMinimum() - 1},
1061                {HOUR_OF_AMPM, time(0, 0, 0, 0), HOUR_OF_AMPM.range().getMaximum() + 1},
1062
1063                {CLOCK_HOUR_OF_AMPM, time(0, 0, 0, 0), CLOCK_HOUR_OF_AMPM.range().getMinimum() - 1},
1064                {CLOCK_HOUR_OF_AMPM, time(0, 0, 0, 0), CLOCK_HOUR_OF_AMPM.range().getMaximum() + 1},
1065
1066                {HOUR_OF_DAY, time(0, 0, 0, 0), HOUR_OF_DAY.range().getMinimum() - 1},
1067                {HOUR_OF_DAY, time(0, 0, 0, 0), HOUR_OF_DAY.range().getMaximum() + 1},
1068
1069                {CLOCK_HOUR_OF_DAY, time(0, 0, 0, 0), CLOCK_HOUR_OF_DAY.range().getMinimum() - 1},
1070                {CLOCK_HOUR_OF_DAY, time(0, 0, 0, 0), CLOCK_HOUR_OF_DAY.range().getMaximum() + 1},
1071
1072                {AMPM_OF_DAY, time(0, 0, 0, 0), AMPM_OF_DAY.range().getMinimum() - 1},
1073                {AMPM_OF_DAY, time(0, 0, 0, 0), AMPM_OF_DAY.range().getMaximum() + 1},
1074        };
1075    }
1076
1077    @Test(dataProvider = "withTemporalField_outOfRange")
1078    public void test_with_longTemporalField_invalid(TemporalField field, LocalTime base, long newValue) {
1079        try {
1080            base.with(field, newValue);
1081            fail("Field should not be allowed " + field);
1082        } catch (DateTimeException ex) {
1083            // expected
1084        }
1085    }
1086
1087    // All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.
1088    @Test(expectedExceptions=UnsupportedTemporalTypeException.class)
1089    public void test_with_longTemporalField_otherChronoField() {
1090        TEST_12_30_40_987654321.with(ChronoField.DAY_OF_MONTH, 1);
1091    }
1092
1093    // If the field is not a {@code ChronoField}, then the result of this method
1094    // is obtained by invoking {@code TemporalField.adjustInto(Temporal, long)}
1095    // passing {@code this} as the argument.
1096    @Test
1097    public void test_with_longTemporalField_notChronoField() {
1098        final LocalTime result = LocalTime.of(12, 30);
1099        final LocalTime base = LocalTime.of(15, 45);
1100        TemporalField field = new TemporalField() {
1101            public ValueRange rangeRefinedBy(TemporalAccessor temporal) {
1102                throw new UnsupportedOperationException();
1103            }
1104            public ValueRange range() {
1105                return null;
1106            }
1107            public boolean isTimeBased() {
1108                throw new UnsupportedOperationException();
1109            }
1110            public boolean isSupportedBy(TemporalAccessor temporal) {
1111                throw new UnsupportedOperationException();
1112            }
1113            public boolean isDateBased() {
1114                throw new UnsupportedOperationException();
1115            }
1116            public TemporalUnit getRangeUnit() {
1117                throw new UnsupportedOperationException();
1118            }
1119            public long getFrom(TemporalAccessor temporal) {
1120                throw new UnsupportedOperationException();
1121            }
1122            public TemporalUnit getBaseUnit() {
1123                throw new UnsupportedOperationException();
1124            }
1125            public <R extends Temporal> R adjustInto(R temporal, long newValue) {
1126                assertEquals(temporal, base);
1127                assertEquals(newValue, 12L);
1128                @SuppressWarnings("unchecked")
1129                R r = (R) result;
1130                return r;
1131            }
1132        };
1133        LocalTime test = base.with(field, 12L);
1134        assertSame(test, result);
1135    }
1136
1137    @Test(expectedExceptions=NullPointerException.class)
1138    public void test_with_longTemporalField_null() {
1139        TEST_12_30_40_987654321.with((TemporalField) null, 1);
1140    }
1141
1142    //-----------------------------------------------------------------------
1143    // withHour()
1144    //-----------------------------------------------------------------------
1145    @Test
1146    public void test_withHour_normal() {
1147        LocalTime t = TEST_12_30_40_987654321;
1148        for (int i = 0; i < 24; i++) {
1149            t = t.withHour(i);
1150            assertEquals(t.getHour(), i);
1151        }
1152    }
1153
1154    @Test
1155    public void test_withHour_noChange_equal() {
1156        LocalTime t = TEST_12_30_40_987654321.withHour(12);
1157        assertEquals(t, TEST_12_30_40_987654321);
1158    }
1159
1160    @Test
1161    public void test_withHour_toMidnight_equal() {
1162        LocalTime t = LocalTime.of(1, 0).withHour(0);
1163        assertEquals(t, LocalTime.MIDNIGHT);
1164    }
1165
1166    @Test
1167    public void test_withHour_toMidday_equal() {
1168        LocalTime t = LocalTime.of(1, 0).withHour(12);
1169        assertEquals(t, LocalTime.NOON);
1170    }
1171
1172    @Test(expectedExceptions=DateTimeException.class)
1173    public void test_withHour_hourTooLow() {
1174        TEST_12_30_40_987654321.withHour(-1);
1175    }
1176
1177    @Test(expectedExceptions=DateTimeException.class)
1178    public void test_withHour_hourTooHigh() {
1179        TEST_12_30_40_987654321.withHour(24);
1180    }
1181
1182    //-----------------------------------------------------------------------
1183    // withMinute()
1184    //-----------------------------------------------------------------------
1185    @Test
1186    public void test_withMinute_normal() {
1187        LocalTime t = TEST_12_30_40_987654321;
1188        for (int i = 0; i < 60; i++) {
1189            t = t.withMinute(i);
1190            assertEquals(t.getMinute(), i);
1191        }
1192    }
1193
1194    @Test
1195    public void test_withMinute_noChange_equal() {
1196        LocalTime t = TEST_12_30_40_987654321.withMinute(30);
1197        assertEquals(t, TEST_12_30_40_987654321);
1198    }
1199
1200    @Test
1201    public void test_withMinute_toMidnight_equal() {
1202        LocalTime t = LocalTime.of(0, 1).withMinute(0);
1203        assertEquals(t, LocalTime.MIDNIGHT);
1204    }
1205
1206    @Test
1207    public void test_withMinute_toMidday_equals() {
1208        LocalTime t = LocalTime.of(12, 1).withMinute(0);
1209        assertEquals(t, LocalTime.NOON);
1210    }
1211
1212    @Test(expectedExceptions=DateTimeException.class)
1213    public void test_withMinute_minuteTooLow() {
1214        TEST_12_30_40_987654321.withMinute(-1);
1215    }
1216
1217    @Test(expectedExceptions=DateTimeException.class)
1218    public void test_withMinute_minuteTooHigh() {
1219        TEST_12_30_40_987654321.withMinute(60);
1220    }
1221
1222    //-----------------------------------------------------------------------
1223    // withSecond()
1224    //-----------------------------------------------------------------------
1225    @Test
1226    public void test_withSecond_normal() {
1227        LocalTime t = TEST_12_30_40_987654321;
1228        for (int i = 0; i < 60; i++) {
1229            t = t.withSecond(i);
1230            assertEquals(t.getSecond(), i);
1231        }
1232    }
1233
1234    @Test
1235    public void test_withSecond_noChange_equal() {
1236        LocalTime t = TEST_12_30_40_987654321.withSecond(40);
1237        assertEquals(t, TEST_12_30_40_987654321);
1238    }
1239
1240    @Test
1241    public void test_withSecond_toMidnight_equal() {
1242        LocalTime t = LocalTime.of(0, 0, 1).withSecond(0);
1243        assertEquals(t, LocalTime.MIDNIGHT);
1244    }
1245
1246    @Test
1247    public void test_withSecond_toMidday_equal() {
1248        LocalTime t = LocalTime.of(12, 0, 1).withSecond(0);
1249        assertEquals(t, LocalTime.NOON);
1250    }
1251
1252    @Test(expectedExceptions=DateTimeException.class)
1253    public void test_withSecond_secondTooLow() {
1254        TEST_12_30_40_987654321.withSecond(-1);
1255    }
1256
1257    @Test(expectedExceptions=DateTimeException.class)
1258    public void test_withSecond_secondTooHigh() {
1259        TEST_12_30_40_987654321.withSecond(60);
1260    }
1261
1262    //-----------------------------------------------------------------------
1263    // withNano()
1264    //-----------------------------------------------------------------------
1265    @Test
1266    public void test_withNanoOfSecond_normal() {
1267        LocalTime t = TEST_12_30_40_987654321;
1268        t = t.withNano(1);
1269        assertEquals(t.getNano(), 1);
1270        t = t.withNano(10);
1271        assertEquals(t.getNano(), 10);
1272        t = t.withNano(100);
1273        assertEquals(t.getNano(), 100);
1274        t = t.withNano(999999999);
1275        assertEquals(t.getNano(), 999999999);
1276    }
1277
1278    @Test
1279    public void test_withNanoOfSecond_noChange_equal() {
1280        LocalTime t = TEST_12_30_40_987654321.withNano(987654321);
1281        assertEquals(t, TEST_12_30_40_987654321);
1282    }
1283
1284    @Test
1285    public void test_withNanoOfSecond_toMidnight_equal() {
1286        LocalTime t = LocalTime.of(0, 0, 0, 1).withNano(0);
1287        assertEquals(t, LocalTime.MIDNIGHT);
1288    }
1289
1290    @Test
1291    public void test_withNanoOfSecond_toMidday_equal() {
1292        LocalTime t = LocalTime.of(12, 0, 0, 1).withNano(0);
1293        assertEquals(t, LocalTime.NOON);
1294    }
1295
1296    @Test(expectedExceptions=DateTimeException.class)
1297    public void test_withNanoOfSecond_nanoTooLow() {
1298        TEST_12_30_40_987654321.withNano(-1);
1299    }
1300
1301    @Test(expectedExceptions=DateTimeException.class)
1302    public void test_withNanoOfSecond_nanoTooHigh() {
1303        TEST_12_30_40_987654321.withNano(1000000000);
1304    }
1305
1306    //-----------------------------------------------------------------------
1307    // truncated(TemporalUnit)
1308    //-----------------------------------------------------------------------
1309    TemporalUnit NINETY_MINS = new TemporalUnit() {
1310        @Override
1311        public Duration getDuration() {
1312            return Duration.ofMinutes(90);
1313        }
1314        @Override
1315        public boolean isDurationEstimated() {
1316            return false;
1317        }
1318        @Override
1319        public boolean isDateBased() {
1320            return false;
1321        }
1322        @Override
1323        public boolean isTimeBased() {
1324            return true;
1325        }
1326        @Override
1327        public boolean isSupportedBy(Temporal temporal) {
1328            return false;
1329        }
1330        @Override
1331        public <R extends Temporal> R addTo(R temporal, long amount) {
1332            throw new UnsupportedOperationException();
1333        }
1334        @Override
1335        public long between(Temporal temporal1, Temporal temporal2) {
1336            throw new UnsupportedOperationException();
1337        }
1338        @Override
1339        public String toString() {
1340            return "NinetyMins";
1341        }
1342    };
1343
1344    TemporalUnit NINETY_FIVE_MINS = new TemporalUnit() {
1345        @Override
1346        public Duration getDuration() {
1347            return Duration.ofMinutes(95);
1348        }
1349        @Override
1350        public boolean isDurationEstimated() {
1351            return false;
1352        }
1353        @Override
1354        public boolean isDateBased() {
1355            return false;
1356        }
1357        @Override
1358        public boolean isTimeBased() {
1359            return false;
1360        }
1361        @Override
1362        public boolean isSupportedBy(Temporal temporal) {
1363            return false;
1364        }
1365        @Override
1366        public <R extends Temporal> R addTo(R temporal, long amount) {
1367            throw new UnsupportedOperationException();
1368        }
1369        @Override
1370        public long between(Temporal temporal1, Temporal temporal2) {
1371            throw new UnsupportedOperationException();
1372        }
1373        @Override
1374        public String toString() {
1375            return "NinetyFiveMins";
1376        }
1377    };
1378
1379    @DataProvider(name="truncatedToValid")
1380    Object[][] data_truncatedToValid() {
1381        return new Object[][] {
1382            {LocalTime.of(1, 2, 3, 123_456_789), NANOS, LocalTime.of(1, 2, 3, 123_456_789)},
1383            {LocalTime.of(1, 2, 3, 123_456_789), MICROS, LocalTime.of(1, 2, 3, 123_456_000)},
1384            {LocalTime.of(1, 2, 3, 123_456_789), MILLIS, LocalTime.of(1, 2, 3, 1230_00_000)},
1385            {LocalTime.of(1, 2, 3, 123_456_789), SECONDS, LocalTime.of(1, 2, 3)},
1386            {LocalTime.of(1, 2, 3, 123_456_789), MINUTES, LocalTime.of(1, 2)},
1387            {LocalTime.of(1, 2, 3, 123_456_789), HOURS, LocalTime.of(1, 0)},
1388            {LocalTime.of(1, 2, 3, 123_456_789), DAYS, LocalTime.MIDNIGHT},
1389
1390            {LocalTime.of(1, 1, 1, 123_456_789), NINETY_MINS, LocalTime.of(0, 0)},
1391            {LocalTime.of(2, 1, 1, 123_456_789), NINETY_MINS, LocalTime.of(1, 30)},
1392            {LocalTime.of(3, 1, 1, 123_456_789), NINETY_MINS, LocalTime.of(3, 0)},
1393        };
1394    }
1395
1396    @Test(dataProvider="truncatedToValid")
1397    public void test_truncatedTo_valid(LocalTime input, TemporalUnit unit, LocalTime expected) {
1398        assertEquals(input.truncatedTo(unit), expected);
1399    }
1400
1401    @DataProvider(name="truncatedToInvalid")
1402    Object[][] data_truncatedToInvalid() {
1403        return new Object[][] {
1404            {LocalTime.of(1, 2, 3, 123_456_789), NINETY_FIVE_MINS},
1405            {LocalTime.of(1, 2, 3, 123_456_789), WEEKS},
1406            {LocalTime.of(1, 2, 3, 123_456_789), MONTHS},
1407            {LocalTime.of(1, 2, 3, 123_456_789), YEARS},
1408        };
1409    }
1410
1411    @Test(dataProvider="truncatedToInvalid", expectedExceptions=DateTimeException.class)
1412    public void test_truncatedTo_invalid(LocalTime input, TemporalUnit unit) {
1413        input.truncatedTo(unit);
1414    }
1415
1416    @Test(expectedExceptions=NullPointerException.class)
1417    public void test_truncatedTo_null() {
1418        TEST_12_30_40_987654321.truncatedTo(null);
1419    }
1420
1421    //-----------------------------------------------------------------------
1422    // plus(TemporalAmount)
1423    //-----------------------------------------------------------------------
1424    @Test
1425    public void test_plus_TemporalAmount_positiveHours() {
1426        TemporalAmount period = MockSimplePeriod.of(7, ChronoUnit.HOURS);
1427        LocalTime t = TEST_12_30_40_987654321.plus(period);
1428        assertEquals(t, LocalTime.of(19, 30, 40, 987654321));
1429    }
1430
1431    @Test
1432    public void test_plus_TemporalAmount_negativeMinutes() {
1433        TemporalAmount period = MockSimplePeriod.of(-25, ChronoUnit.MINUTES);
1434        LocalTime t = TEST_12_30_40_987654321.plus(period);
1435        assertEquals(t, LocalTime.of(12, 5, 40, 987654321));
1436    }
1437
1438    @Test
1439    public void test_plus_TemporalAmount_zero() {
1440        TemporalAmount period = Period.ZERO;
1441        LocalTime t = TEST_12_30_40_987654321.plus(period);
1442        assertEquals(t, TEST_12_30_40_987654321);
1443    }
1444
1445    @Test
1446    public void test_plus_TemporalAmount_wrap() {
1447        TemporalAmount p = MockSimplePeriod.of(1, HOURS);
1448        LocalTime t = LocalTime.of(23, 30).plus(p);
1449        assertEquals(t, LocalTime.of(0, 30));
1450    }
1451
1452    @Test(expectedExceptions=DateTimeException.class)
1453    public void test_plus_TemporalAmount_dateNotAllowed() {
1454        TemporalAmount period = MockSimplePeriod.of(7, ChronoUnit.MONTHS);
1455        TEST_12_30_40_987654321.plus(period);
1456    }
1457
1458    @Test(expectedExceptions=NullPointerException.class)
1459    public void test_plus_TemporalAmount_null() {
1460        TEST_12_30_40_987654321.plus((TemporalAmount) null);
1461    }
1462
1463    //-----------------------------------------------------------------------
1464    // plus(long,TemporalUnit)
1465    //-----------------------------------------------------------------------
1466    @Test
1467    public void test_plus_longTemporalUnit_positiveHours() {
1468        LocalTime t = TEST_12_30_40_987654321.plus(7, ChronoUnit.HOURS);
1469        assertEquals(t, LocalTime.of(19, 30, 40, 987654321));
1470    }
1471
1472    @Test
1473    public void test_plus_longTemporalUnit_negativeMinutes() {
1474        LocalTime t = TEST_12_30_40_987654321.plus(-25, ChronoUnit.MINUTES);
1475        assertEquals(t, LocalTime.of(12, 5, 40, 987654321));
1476    }
1477
1478    @Test
1479    public void test_plus_longTemporalUnit_zero() {
1480        LocalTime t = TEST_12_30_40_987654321.plus(0, ChronoUnit.MINUTES);
1481        assertEquals(t, TEST_12_30_40_987654321);
1482    }
1483
1484    @Test
1485    public void test_plus_longTemporalUnit_invalidUnit() {
1486        for (TemporalUnit unit : INVALID_UNITS) {
1487            try {
1488                TEST_12_30_40_987654321.plus(1, unit);
1489                fail("Unit should not be allowed " + unit);
1490            } catch (DateTimeException ex) {
1491                // expected
1492            }
1493        }
1494    }
1495
1496    @Test(expectedExceptions=NullPointerException.class)
1497    public void test_plus_longTemporalUnit_null() {
1498        TEST_12_30_40_987654321.plus(1, (TemporalUnit) null);
1499    }
1500
1501    //-----------------------------------------------------------------------
1502    // plusHours()
1503    //-----------------------------------------------------------------------
1504    @Test
1505    public void test_plusHours_one() {
1506        LocalTime t = LocalTime.MIDNIGHT;
1507        for (int i = 0; i < 50; i++) {
1508            t = t.plusHours(1);
1509            assertEquals(t.getHour(), (i + 1) % 24);
1510        }
1511    }
1512
1513    @Test
1514    public void test_plusHours_fromZero() {
1515        LocalTime base = LocalTime.MIDNIGHT;
1516        for (int i = -50; i < 50; i++) {
1517            LocalTime t = base.plusHours(i);
1518            assertEquals(t.getHour(), (i + 72) % 24);
1519        }
1520    }
1521
1522    @Test
1523    public void test_plusHours_fromOne() {
1524        LocalTime base = LocalTime.of(1, 0);
1525        for (int i = -50; i < 50; i++) {
1526            LocalTime t = base.plusHours(i);
1527            assertEquals(t.getHour(), (1 + i + 72) % 24);
1528        }
1529    }
1530
1531    @Test
1532    public void test_plusHours_noChange_equal() {
1533        LocalTime t = TEST_12_30_40_987654321.plusHours(0);
1534        assertEquals(t, TEST_12_30_40_987654321);
1535    }
1536
1537    @Test
1538    public void test_plusHours_toMidnight_equal() {
1539        LocalTime t = LocalTime.of(23, 0).plusHours(1);
1540        assertEquals(t, LocalTime.MIDNIGHT);
1541    }
1542
1543    @Test
1544    public void test_plusHours_toMidday_equal() {
1545        LocalTime t = LocalTime.of(11, 0).plusHours(1);
1546        assertEquals(t, LocalTime.NOON);
1547    }
1548
1549    @Test
1550    public void test_plusHours_big() {
1551        LocalTime t = LocalTime.of(2, 30).plusHours(Long.MAX_VALUE);
1552        int hours = (int) (Long.MAX_VALUE % 24L);
1553        assertEquals(t, LocalTime.of(2, 30).plusHours(hours));
1554    }
1555
1556    //-----------------------------------------------------------------------
1557    // plusMinutes()
1558    //-----------------------------------------------------------------------
1559    @Test
1560    public void test_plusMinutes_one() {
1561        LocalTime t = LocalTime.MIDNIGHT;
1562        int hour = 0;
1563        int min = 0;
1564        for (int i = 0; i < 70; i++) {
1565            t = t.plusMinutes(1);
1566            min++;
1567            if (min == 60) {
1568                hour++;
1569                min = 0;
1570            }
1571            assertEquals(t.getHour(), hour);
1572            assertEquals(t.getMinute(), min);
1573        }
1574    }
1575
1576    @Test
1577    public void test_plusMinutes_fromZero() {
1578        LocalTime base = LocalTime.MIDNIGHT;
1579        int hour;
1580        int min;
1581        for (int i = -70; i < 70; i++) {
1582            LocalTime t = base.plusMinutes(i);
1583            if (i < -60) {
1584                hour = 22;
1585                min = i + 120;
1586            } else if (i < 0) {
1587                hour = 23;
1588                min = i + 60;
1589            } else if (i >= 60) {
1590                hour = 1;
1591                min = i - 60;
1592            } else {
1593                hour = 0;
1594                min = i;
1595            }
1596            assertEquals(t.getHour(), hour);
1597            assertEquals(t.getMinute(), min);
1598        }
1599    }
1600
1601    @Test
1602    public void test_plusMinutes_noChange_equal() {
1603        LocalTime t = TEST_12_30_40_987654321.plusMinutes(0);
1604        assertEquals(t, TEST_12_30_40_987654321);
1605    }
1606
1607    @Test
1608    public void test_plusMinutes_noChange_oneDay_equal() {
1609        LocalTime t = TEST_12_30_40_987654321.plusMinutes(24 * 60);
1610        assertEquals(t, TEST_12_30_40_987654321);
1611    }
1612
1613    @Test
1614    public void test_plusMinutes_toMidnight_equal() {
1615        LocalTime t = LocalTime.of(23, 59).plusMinutes(1);
1616        assertEquals(t, LocalTime.MIDNIGHT);
1617    }
1618
1619    @Test
1620    public void test_plusMinutes_toMidday_equal() {
1621        LocalTime t = LocalTime.of(11, 59).plusMinutes(1);
1622        assertEquals(t, LocalTime.NOON);
1623    }
1624
1625    @Test
1626    public void test_plusMinutes_big() {
1627        LocalTime t = LocalTime.of(2, 30).plusMinutes(Long.MAX_VALUE);
1628        int mins = (int) (Long.MAX_VALUE % (24L * 60L));
1629        assertEquals(t, LocalTime.of(2, 30).plusMinutes(mins));
1630    }
1631
1632    //-----------------------------------------------------------------------
1633    // plusSeconds()
1634    //-----------------------------------------------------------------------
1635    @Test
1636    public void test_plusSeconds_one() {
1637        LocalTime t = LocalTime.MIDNIGHT;
1638        int hour = 0;
1639        int min = 0;
1640        int sec = 0;
1641        for (int i = 0; i < 3700; i++) {
1642            t = t.plusSeconds(1);
1643            sec++;
1644            if (sec == 60) {
1645                min++;
1646                sec = 0;
1647            }
1648            if (min == 60) {
1649                hour++;
1650                min = 0;
1651            }
1652            assertEquals(t.getHour(), hour);
1653            assertEquals(t.getMinute(), min);
1654            assertEquals(t.getSecond(), sec);
1655        }
1656    }
1657
1658    @DataProvider(name="plusSeconds_fromZero")
1659    Iterator<Object[]> plusSeconds_fromZero() {
1660        return new Iterator<Object[]>() {
1661            int delta = 30;
1662            int i = -3660;
1663            int hour = 22;
1664            int min = 59;
1665            int sec = 0;
1666
1667            public boolean hasNext() {
1668                return i <= 3660;
1669            }
1670
1671            public Object[] next() {
1672                final Object[] ret = new Object[] {i, hour, min, sec};
1673                i += delta;
1674                sec += delta;
1675
1676                if (sec >= 60) {
1677                    min++;
1678                    sec -= 60;
1679
1680                    if (min == 60) {
1681                        hour++;
1682                        min = 0;
1683
1684                        if (hour == 24) {
1685                            hour = 0;
1686                        }
1687                    }
1688                }
1689
1690                return ret;
1691            }
1692
1693            public void remove() {
1694                throw new UnsupportedOperationException();
1695            }
1696        };
1697    }
1698
1699    @Test(dataProvider="plusSeconds_fromZero")
1700    public void test_plusSeconds_fromZero(int seconds, int hour, int min, int sec) {
1701        LocalTime base = LocalTime.MIDNIGHT;
1702        LocalTime t = base.plusSeconds(seconds);
1703
1704        assertEquals(hour, t.getHour());
1705        assertEquals(min, t.getMinute());
1706        assertEquals(sec, t.getSecond());
1707    }
1708
1709    @Test
1710    public void test_plusSeconds_noChange_equal() {
1711        LocalTime t = TEST_12_30_40_987654321.plusSeconds(0);
1712        assertEquals(t, TEST_12_30_40_987654321);
1713    }
1714
1715    @Test
1716    public void test_plusSeconds_noChange_oneDay_equal() {
1717        LocalTime t = TEST_12_30_40_987654321.plusSeconds(24 * 60 * 60);
1718        assertEquals(t, TEST_12_30_40_987654321);
1719    }
1720
1721    @Test
1722    public void test_plusSeconds_toMidnight_equal() {
1723        LocalTime t = LocalTime.of(23, 59, 59).plusSeconds(1);
1724        assertEquals(t, LocalTime.MIDNIGHT);
1725    }
1726
1727    @Test
1728    public void test_plusSeconds_toMidday_equal() {
1729        LocalTime t = LocalTime.of(11, 59, 59).plusSeconds(1);
1730        assertEquals(t, LocalTime.NOON);
1731    }
1732
1733    //-----------------------------------------------------------------------
1734    // plusNanos()
1735    //-----------------------------------------------------------------------
1736    @Test
1737    public void test_plusNanos_halfABillion() {
1738        LocalTime t = LocalTime.MIDNIGHT;
1739        int hour = 0;
1740        int min = 0;
1741        int sec = 0;
1742        int nanos = 0;
1743        for (long i = 0; i < 3700 * 1000000000L; i+= 500000000) {
1744            t = t.plusNanos(500000000);
1745            nanos += 500000000;
1746            if (nanos == 1000000000) {
1747                sec++;
1748                nanos = 0;
1749            }
1750            if (sec == 60) {
1751                min++;
1752                sec = 0;
1753            }
1754            if (min == 60) {
1755                hour++;
1756                min = 0;
1757            }
1758            assertEquals(t.getHour(), hour);
1759            assertEquals(t.getMinute(), min);
1760            assertEquals(t.getSecond(), sec);
1761            assertEquals(t.getNano(), nanos);
1762        }
1763    }
1764
1765    @DataProvider(name="plusNanos_fromZero")
1766    Iterator<Object[]> plusNanos_fromZero() {
1767        return new Iterator<Object[]>() {
1768            long delta = 7500000000L;
1769            long i = -3660 * 1000000000L;
1770            int hour = 22;
1771            int min = 59;
1772            int sec = 0;
1773            long nanos = 0;
1774
1775            public boolean hasNext() {
1776                return i <= 3660 * 1000000000L;
1777            }
1778
1779            public Object[] next() {
1780                final Object[] ret = new Object[] {i, hour, min, sec, (int)nanos};
1781                i += delta;
1782                nanos += delta;
1783
1784                if (nanos >= 1000000000L) {
1785                    sec += nanos / 1000000000L;
1786                    nanos %= 1000000000L;
1787
1788                    if (sec >= 60) {
1789                        min++;
1790                        sec %= 60;
1791
1792                        if (min == 60) {
1793                            hour++;
1794                            min = 0;
1795
1796                            if (hour == 24) {
1797                                hour = 0;
1798                            }
1799                        }
1800                    }
1801                }
1802
1803                return ret;
1804            }
1805
1806            public void remove() {
1807                throw new UnsupportedOperationException();
1808            }
1809        };
1810    }
1811
1812    @Test(dataProvider="plusNanos_fromZero")
1813    public void test_plusNanos_fromZero(long nanoseconds, int hour, int min, int sec, int nanos) {
1814        LocalTime base = LocalTime.MIDNIGHT;
1815        LocalTime t = base.plusNanos(nanoseconds);
1816
1817        assertEquals(hour, t.getHour());
1818        assertEquals(min, t.getMinute());
1819        assertEquals(sec, t.getSecond());
1820        assertEquals(nanos, t.getNano());
1821    }
1822
1823    @Test
1824    public void test_plusNanos_noChange_equal() {
1825        LocalTime t = TEST_12_30_40_987654321.plusNanos(0);
1826        assertEquals(t, TEST_12_30_40_987654321);
1827    }
1828
1829    @Test
1830    public void test_plusNanos_noChange_oneDay_equal() {
1831        LocalTime t = TEST_12_30_40_987654321.plusNanos(24 * 60 * 60 * 1000000000L);
1832        assertEquals(t, TEST_12_30_40_987654321);
1833    }
1834
1835    @Test
1836    public void test_plusNanos_toMidnight_equal() {
1837        LocalTime t = LocalTime.of(23, 59, 59, 999999999).plusNanos(1);
1838        assertEquals(t, LocalTime.MIDNIGHT);
1839    }
1840
1841    @Test
1842    public void test_plusNanos_toMidday_equal() {
1843        LocalTime t = LocalTime.of(11, 59, 59, 999999999).plusNanos(1);
1844        assertEquals(t, LocalTime.NOON);
1845    }
1846
1847    //-----------------------------------------------------------------------
1848    // minus(TemporalAmount)
1849    //-----------------------------------------------------------------------
1850    @Test
1851    public void test_minus_TemporalAmount_positiveHours() {
1852        TemporalAmount period = MockSimplePeriod.of(7, ChronoUnit.HOURS);
1853        LocalTime t = TEST_12_30_40_987654321.minus(period);
1854        assertEquals(t, LocalTime.of(5, 30, 40, 987654321));
1855    }
1856
1857    @Test
1858    public void test_minus_TemporalAmount_negativeMinutes() {
1859        TemporalAmount period = MockSimplePeriod.of(-25, ChronoUnit.MINUTES);
1860        LocalTime t = TEST_12_30_40_987654321.minus(period);
1861        assertEquals(t, LocalTime.of(12, 55, 40, 987654321));
1862    }
1863
1864    @Test
1865    public void test_minus_TemporalAmount_zero() {
1866        TemporalAmount period = Period.ZERO;
1867        LocalTime t = TEST_12_30_40_987654321.minus(period);
1868        assertEquals(t, TEST_12_30_40_987654321);
1869    }
1870
1871    @Test
1872    public void test_minus_TemporalAmount_wrap() {
1873        TemporalAmount p = MockSimplePeriod.of(1, HOURS);
1874        LocalTime t = LocalTime.of(0, 30).minus(p);
1875        assertEquals(t, LocalTime.of(23, 30));
1876    }
1877
1878    @Test(expectedExceptions=DateTimeException.class)
1879    public void test_minus_TemporalAmount_dateNotAllowed() {
1880        TemporalAmount period = MockSimplePeriod.of(7, ChronoUnit.MONTHS);
1881        TEST_12_30_40_987654321.minus(period);
1882    }
1883
1884    @Test(expectedExceptions=NullPointerException.class)
1885    public void test_minus_TemporalAmount_null() {
1886        TEST_12_30_40_987654321.minus((TemporalAmount) null);
1887    }
1888
1889    //-----------------------------------------------------------------------
1890    // minus(long,TemporalUnit)
1891    //-----------------------------------------------------------------------
1892    @Test
1893    public void test_minus_longTemporalUnit_positiveHours() {
1894        LocalTime t = TEST_12_30_40_987654321.minus(7, ChronoUnit.HOURS);
1895        assertEquals(t, LocalTime.of(5, 30, 40, 987654321));
1896    }
1897
1898    @Test
1899    public void test_minus_longTemporalUnit_negativeMinutes() {
1900        LocalTime t = TEST_12_30_40_987654321.minus(-25, ChronoUnit.MINUTES);
1901        assertEquals(t, LocalTime.of(12, 55, 40, 987654321));
1902    }
1903
1904    @Test
1905    public void test_minus_longTemporalUnit_zero() {
1906        LocalTime t = TEST_12_30_40_987654321.minus(0, ChronoUnit.MINUTES);
1907        assertEquals(t, TEST_12_30_40_987654321);
1908    }
1909
1910    @Test
1911    public void test_minus_longTemporalUnit_invalidUnit() {
1912        for (TemporalUnit unit : INVALID_UNITS) {
1913            try {
1914                TEST_12_30_40_987654321.minus(1, unit);
1915                fail("Unit should not be allowed " + unit);
1916            } catch (DateTimeException ex) {
1917                // expected
1918            }
1919        }
1920    }
1921
1922    @Test(expectedExceptions=NullPointerException.class)
1923    public void test_minus_longTemporalUnit_null() {
1924        TEST_12_30_40_987654321.minus(1, (TemporalUnit) null);
1925    }
1926
1927    //-----------------------------------------------------------------------
1928    // minusHours()
1929    //-----------------------------------------------------------------------
1930    @Test
1931    public void test_minusHours_one() {
1932        LocalTime t = LocalTime.MIDNIGHT;
1933        for (int i = 0; i < 50; i++) {
1934            t = t.minusHours(1);
1935            assertEquals(t.getHour(), (((-i + 23) % 24) + 24) % 24, String.valueOf(i));
1936        }
1937    }
1938
1939    @Test
1940    public void test_minusHours_fromZero() {
1941        LocalTime base = LocalTime.MIDNIGHT;
1942        for (int i = -50; i < 50; i++) {
1943            LocalTime t = base.minusHours(i);
1944            assertEquals(t.getHour(), ((-i % 24) + 24) % 24);
1945        }
1946    }
1947
1948    @Test
1949    public void test_minusHours_fromOne() {
1950        LocalTime base = LocalTime.of(1, 0);
1951        for (int i = -50; i < 50; i++) {
1952            LocalTime t = base.minusHours(i);
1953            assertEquals(t.getHour(), (1 + (-i % 24) + 24) % 24);
1954        }
1955    }
1956
1957    @Test
1958    public void test_minusHours_noChange_equal() {
1959        LocalTime t = TEST_12_30_40_987654321.minusHours(0);
1960        assertEquals(t, TEST_12_30_40_987654321);
1961    }
1962
1963    @Test
1964    public void test_minusHours_toMidnight_equal() {
1965        LocalTime t = LocalTime.of(1, 0).minusHours(1);
1966        assertEquals(t, LocalTime.MIDNIGHT);
1967    }
1968
1969    @Test
1970    public void test_minusHours_toMidday_equal() {
1971        LocalTime t = LocalTime.of(13, 0).minusHours(1);
1972        assertEquals(t, LocalTime.NOON);
1973    }
1974
1975    @Test
1976    public void test_minusHours_big() {
1977        LocalTime t = LocalTime.of(2, 30).minusHours(Long.MAX_VALUE);
1978        int hours = (int) (Long.MAX_VALUE % 24L);
1979        assertEquals(t, LocalTime.of(2, 30).minusHours(hours));
1980    }
1981
1982    //-----------------------------------------------------------------------
1983    // minusMinutes()
1984    //-----------------------------------------------------------------------
1985    @Test
1986    public void test_minusMinutes_one() {
1987        LocalTime t = LocalTime.MIDNIGHT;
1988        int hour = 0;
1989        int min = 0;
1990        for (int i = 0; i < 70; i++) {
1991            t = t.minusMinutes(1);
1992            min--;
1993            if (min == -1) {
1994                hour--;
1995                min = 59;
1996
1997                if (hour == -1) {
1998                    hour = 23;
1999                }
2000            }
2001            assertEquals(t.getHour(), hour);
2002            assertEquals(t.getMinute(), min);
2003        }
2004    }
2005
2006    @Test
2007    public void test_minusMinutes_fromZero() {
2008        LocalTime base = LocalTime.MIDNIGHT;
2009        int hour = 22;
2010        int min = 49;
2011        for (int i = 70; i > -70; i--) {
2012            LocalTime t = base.minusMinutes(i);
2013            min++;
2014
2015            if (min == 60) {
2016                hour++;
2017                min = 0;
2018
2019                if (hour == 24) {
2020                    hour = 0;
2021                }
2022            }
2023
2024            assertEquals(t.getHour(), hour);
2025            assertEquals(t.getMinute(), min);
2026        }
2027    }
2028
2029    @Test
2030    public void test_minusMinutes_noChange_equal() {
2031        LocalTime t = TEST_12_30_40_987654321.minusMinutes(0);
2032        assertEquals(t, TEST_12_30_40_987654321);
2033    }
2034
2035    @Test
2036    public void test_minusMinutes_noChange_oneDay_equal() {
2037        LocalTime t = TEST_12_30_40_987654321.minusMinutes(24 * 60);
2038        assertEquals(t, TEST_12_30_40_987654321);
2039    }
2040
2041    @Test
2042    public void test_minusMinutes_toMidnight_equal() {
2043        LocalTime t = LocalTime.of(0, 1).minusMinutes(1);
2044        assertEquals(t, LocalTime.MIDNIGHT);
2045    }
2046
2047    @Test
2048    public void test_minusMinutes_toMidday_equals() {
2049        LocalTime t = LocalTime.of(12, 1).minusMinutes(1);
2050        assertEquals(t, LocalTime.NOON);
2051    }
2052
2053    @Test
2054    public void test_minusMinutes_big() {
2055        LocalTime t = LocalTime.of(2, 30).minusMinutes(Long.MAX_VALUE);
2056        int mins = (int) (Long.MAX_VALUE % (24L * 60L));
2057        assertEquals(t, LocalTime.of(2, 30).minusMinutes(mins));
2058    }
2059
2060    //-----------------------------------------------------------------------
2061    // minusSeconds()
2062    //-----------------------------------------------------------------------
2063    @Test
2064    public void test_minusSeconds_one() {
2065        LocalTime t = LocalTime.MIDNIGHT;
2066        int hour = 0;
2067        int min = 0;
2068        int sec = 0;
2069        for (int i = 0; i < 3700; i++) {
2070            t = t.minusSeconds(1);
2071            sec--;
2072            if (sec == -1) {
2073                min--;
2074                sec = 59;
2075
2076                if (min == -1) {
2077                    hour--;
2078                    min = 59;
2079
2080                    if (hour == -1) {
2081                        hour = 23;
2082                    }
2083                }
2084            }
2085            assertEquals(t.getHour(), hour);
2086            assertEquals(t.getMinute(), min);
2087            assertEquals(t.getSecond(), sec);
2088        }
2089    }
2090
2091    @DataProvider(name="minusSeconds_fromZero")
2092    Iterator<Object[]> minusSeconds_fromZero() {
2093        return new Iterator<Object[]>() {
2094            int delta = 30;
2095            int i = 3660;
2096            int hour = 22;
2097            int min = 59;
2098            int sec = 0;
2099
2100            public boolean hasNext() {
2101                return i >= -3660;
2102            }
2103
2104            public Object[] next() {
2105                final Object[] ret = new Object[] {i, hour, min, sec};
2106                i -= delta;
2107                sec += delta;
2108
2109                if (sec >= 60) {
2110                    min++;
2111                    sec -= 60;
2112
2113                    if (min == 60) {
2114                        hour++;
2115                        min = 0;
2116
2117                        if (hour == 24) {
2118                            hour = 0;
2119                        }
2120                    }
2121                }
2122
2123                return ret;
2124            }
2125
2126            public void remove() {
2127                throw new UnsupportedOperationException();
2128            }
2129        };
2130    }
2131
2132    @Test(dataProvider="minusSeconds_fromZero")
2133    public void test_minusSeconds_fromZero(int seconds, int hour, int min, int sec) {
2134        LocalTime base = LocalTime.MIDNIGHT;
2135        LocalTime t = base.minusSeconds(seconds);
2136
2137        assertEquals(t.getHour(), hour);
2138        assertEquals(t.getMinute(), min);
2139        assertEquals(t.getSecond(), sec);
2140    }
2141
2142    @Test
2143    public void test_minusSeconds_noChange_equal() {
2144        LocalTime t = TEST_12_30_40_987654321.minusSeconds(0);
2145        assertEquals(t, TEST_12_30_40_987654321);
2146    }
2147
2148    @Test
2149    public void test_minusSeconds_noChange_oneDay_equal() {
2150        LocalTime t = TEST_12_30_40_987654321.minusSeconds(24 * 60 * 60);
2151        assertEquals(t, TEST_12_30_40_987654321);
2152    }
2153
2154    @Test
2155    public void test_minusSeconds_toMidnight_equal() {
2156        LocalTime t = LocalTime.of(0, 0, 1).minusSeconds(1);
2157        assertEquals(t, LocalTime.MIDNIGHT);
2158    }
2159
2160    @Test
2161    public void test_minusSeconds_toMidday_equal() {
2162        LocalTime t = LocalTime.of(12, 0, 1).minusSeconds(1);
2163        assertEquals(t, LocalTime.NOON);
2164    }
2165
2166    @Test
2167    public void test_minusSeconds_big() {
2168        LocalTime t = LocalTime.of(2, 30).minusSeconds(Long.MAX_VALUE);
2169        int secs = (int) (Long.MAX_VALUE % (24L * 60L * 60L));
2170        assertEquals(t, LocalTime.of(2, 30).minusSeconds(secs));
2171    }
2172
2173    //-----------------------------------------------------------------------
2174    // minusNanos()
2175    //-----------------------------------------------------------------------
2176    @Test
2177    public void test_minusNanos_halfABillion() {
2178        LocalTime t = LocalTime.MIDNIGHT;
2179        int hour = 0;
2180        int min = 0;
2181        int sec = 0;
2182        int nanos = 0;
2183        for (long i = 0; i < 3700 * 1000000000L; i+= 500000000) {
2184            t = t.minusNanos(500000000);
2185            nanos -= 500000000;
2186
2187            if (nanos < 0) {
2188                sec--;
2189                nanos += 1000000000;
2190
2191                if (sec == -1) {
2192                    min--;
2193                    sec += 60;
2194
2195                    if (min == -1) {
2196                        hour--;
2197                        min += 60;
2198
2199                        if (hour == -1) {
2200                            hour += 24;
2201                        }
2202                    }
2203                }
2204            }
2205
2206            assertEquals(t.getHour(), hour);
2207            assertEquals(t.getMinute(), min);
2208            assertEquals(t.getSecond(), sec);
2209            assertEquals(t.getNano(), nanos);
2210        }
2211    }
2212
2213    @DataProvider(name="minusNanos_fromZero")
2214    Iterator<Object[]> minusNanos_fromZero() {
2215        return new Iterator<Object[]>() {
2216            long delta = 7500000000L;
2217            long i = 3660 * 1000000000L;
2218            int hour = 22;
2219            int min = 59;
2220            int sec = 0;
2221            long nanos = 0;
2222
2223            public boolean hasNext() {
2224                return i >= -3660 * 1000000000L;
2225            }
2226
2227            public Object[] next() {
2228                final Object[] ret = new Object[] {i, hour, min, sec, (int)nanos};
2229                i -= delta;
2230                nanos += delta;
2231
2232                if (nanos >= 1000000000L) {
2233                    sec += nanos / 1000000000L;
2234                    nanos %= 1000000000L;
2235
2236                    if (sec >= 60) {
2237                        min++;
2238                        sec %= 60;
2239
2240                        if (min == 60) {
2241                            hour++;
2242                            min = 0;
2243
2244                            if (hour == 24) {
2245                                hour = 0;
2246                            }
2247                        }
2248                    }
2249                }
2250
2251                return ret;
2252            }
2253
2254            public void remove() {
2255                throw new UnsupportedOperationException();
2256            }
2257        };
2258    }
2259
2260    @Test(dataProvider="minusNanos_fromZero")
2261    public void test_minusNanos_fromZero(long nanoseconds, int hour, int min, int sec, int nanos) {
2262        LocalTime base = LocalTime.MIDNIGHT;
2263        LocalTime t = base.minusNanos(nanoseconds);
2264
2265        assertEquals(hour, t.getHour());
2266        assertEquals(min, t.getMinute());
2267        assertEquals(sec, t.getSecond());
2268        assertEquals(nanos, t.getNano());
2269    }
2270
2271    @Test
2272    public void test_minusNanos_noChange_equal() {
2273        LocalTime t = TEST_12_30_40_987654321.minusNanos(0);
2274        assertEquals(t, TEST_12_30_40_987654321);
2275    }
2276
2277    @Test
2278    public void test_minusNanos_noChange_oneDay_equal() {
2279        LocalTime t = TEST_12_30_40_987654321.minusNanos(24 * 60 * 60 * 1000000000L);
2280        assertEquals(t, TEST_12_30_40_987654321);
2281    }
2282
2283    @Test
2284    public void test_minusNanos_toMidnight_equal() {
2285        LocalTime t = LocalTime.of(0, 0, 0, 1).minusNanos(1);
2286        assertEquals(t, LocalTime.MIDNIGHT);
2287    }
2288
2289    @Test
2290    public void test_minusNanos_toMidday_equal() {
2291        LocalTime t = LocalTime.of(12, 0, 0, 1).minusNanos(1);
2292        assertEquals(t, LocalTime.NOON);
2293    }
2294
2295    //-----------------------------------------------------------------------
2296    // until(Temporal, TemporalUnit)
2297    //-----------------------------------------------------------------------
2298    @DataProvider(name="periodUntilUnit")
2299    Object[][] data_periodUntilUnit() {
2300        return new Object[][] {
2301                {time(0, 0, 0, 0), time(0, 0, 0, 0), NANOS, 0},
2302                {time(0, 0, 0, 0), time(0, 0, 0, 0), MICROS, 0},
2303                {time(0, 0, 0, 0), time(0, 0, 0, 0), MILLIS, 0},
2304                {time(0, 0, 0, 0), time(0, 0, 0, 0), SECONDS, 0},
2305                {time(0, 0, 0, 0), time(0, 0, 0, 0), MINUTES, 0},
2306                {time(0, 0, 0, 0), time(0, 0, 0, 0), HOURS, 0},
2307                {time(0, 0, 0, 0), time(0, 0, 0, 0), HALF_DAYS, 0},
2308
2309                {time(0, 0, 0, 0), time(2, 0, 0, 0), NANOS, 2 * 3600 * 1_000_000_000L},
2310                {time(0, 0, 0, 0), time(2, 0, 0, 0), MICROS, 2 * 3600 * 1_000_000L},
2311                {time(0, 0, 0, 0), time(2, 0, 0, 0), MILLIS, 2 * 3600 * 1_000L},
2312                {time(0, 0, 0, 0), time(2, 0, 0, 0), SECONDS, 2 * 3600},
2313                {time(0, 0, 0, 0), time(2, 0, 0, 0), MINUTES, 2 * 60},
2314                {time(0, 0, 0, 0), time(2, 0, 0, 0), HOURS, 2},
2315                {time(0, 0, 0, 0), time(2, 0, 0, 0), HALF_DAYS, 0},
2316
2317                {time(0, 0, 0, 0), time(14, 0, 0, 0), NANOS, 14 * 3600 * 1_000_000_000L},
2318                {time(0, 0, 0, 0), time(14, 0, 0, 0), MICROS, 14 * 3600 * 1_000_000L},
2319                {time(0, 0, 0, 0), time(14, 0, 0, 0), MILLIS, 14 * 3600 * 1_000L},
2320                {time(0, 0, 0, 0), time(14, 0, 0, 0), SECONDS, 14 * 3600},
2321                {time(0, 0, 0, 0), time(14, 0, 0, 0), MINUTES, 14 * 60},
2322                {time(0, 0, 0, 0), time(14, 0, 0, 0), HOURS, 14},
2323                {time(0, 0, 0, 0), time(14, 0, 0, 0), HALF_DAYS, 1},
2324
2325                {time(0, 0, 0, 0), time(2, 30, 40, 1500), NANOS, (2 * 3600 + 30 * 60 + 40) * 1_000_000_000L + 1500},
2326                {time(0, 0, 0, 0), time(2, 30, 40, 1500), MICROS, (2 * 3600 + 30 * 60 + 40) * 1_000_000L + 1},
2327                {time(0, 0, 0, 0), time(2, 30, 40, 1500), MILLIS, (2 * 3600 + 30 * 60 + 40) * 1_000L},
2328                {time(0, 0, 0, 0), time(2, 30, 40, 1500), SECONDS, 2 * 3600 + 30 * 60 + 40},
2329                {time(0, 0, 0, 0), time(2, 30, 40, 1500), MINUTES, 2 * 60 + 30},
2330                {time(0, 0, 0, 0), time(2, 30, 40, 1500), HOURS, 2},
2331        };
2332    }
2333
2334    @Test(dataProvider="periodUntilUnit")
2335    public void test_until_TemporalUnit(LocalTime time1, LocalTime time2, TemporalUnit unit, long expected) {
2336        long amount = time1.until(time2, unit);
2337        assertEquals(amount, expected);
2338    }
2339
2340    @Test(dataProvider="periodUntilUnit")
2341    public void test_until_TemporalUnit_negated(LocalTime time1, LocalTime time2, TemporalUnit unit, long expected) {
2342        long amount = time2.until(time1, unit);
2343        assertEquals(amount, -expected);
2344    }
2345
2346    @Test(dataProvider="periodUntilUnit")
2347    public void test_until_TemporalUnit_between(LocalTime time1, LocalTime time2, TemporalUnit unit, long expected) {
2348        long amount = unit.between(time1, time2);
2349        assertEquals(amount, expected);
2350    }
2351
2352    @Test
2353    public void test_until_convertedType() {
2354        LocalTime start = LocalTime.of(11, 30);
2355        LocalDateTime end = start.plusSeconds(2).atDate(LocalDate.of(2010, 6, 30));
2356        assertEquals(start.until(end, SECONDS), 2);
2357    }
2358
2359    @Test(expectedExceptions=DateTimeException.class)
2360    public void test_until_invalidType() {
2361        LocalTime start = LocalTime.of(11, 30);
2362        start.until(LocalDate.of(2010, 6, 30), SECONDS);
2363    }
2364
2365    @Test(expectedExceptions = UnsupportedTemporalTypeException.class)
2366    public void test_until_TemporalUnit_unsupportedUnit() {
2367        TEST_12_30_40_987654321.until(TEST_12_30_40_987654321, DAYS);
2368    }
2369
2370    @Test(expectedExceptions = NullPointerException.class)
2371    public void test_until_TemporalUnit_nullEnd() {
2372        TEST_12_30_40_987654321.until(null, HOURS);
2373    }
2374
2375    @Test(expectedExceptions = NullPointerException.class)
2376    public void test_until_TemporalUnit_nullUnit() {
2377        TEST_12_30_40_987654321.until(TEST_12_30_40_987654321, null);
2378    }
2379
2380    //-----------------------------------------------------------------------
2381    // format(DateTimeFormatter)
2382    //-----------------------------------------------------------------------
2383    @Test
2384    public void test_format_formatter() {
2385        DateTimeFormatter f = DateTimeFormatter.ofPattern("H m s");
2386        String t = LocalTime.of(11, 30, 45).format(f);
2387        assertEquals(t, "11 30 45");
2388    }
2389
2390    @Test(expectedExceptions=NullPointerException.class)
2391    public void test_format_formatter_null() {
2392        LocalTime.of(11, 30, 45).format(null);
2393    }
2394
2395    //-----------------------------------------------------------------------
2396    // atDate()
2397    //-----------------------------------------------------------------------
2398    @Test
2399    public void test_atDate() {
2400        LocalTime t = LocalTime.of(11, 30);
2401        assertEquals(t.atDate(LocalDate.of(2012, 6, 30)), LocalDateTime.of(2012, 6, 30, 11, 30));
2402    }
2403
2404    @Test(expectedExceptions=NullPointerException.class)
2405    public void test_atDate_nullDate() {
2406        TEST_12_30_40_987654321.atDate((LocalDate) null);
2407    }
2408
2409    //-----------------------------------------------------------------------
2410    // atOffset()
2411    //-----------------------------------------------------------------------
2412    @Test
2413    public void test_atOffset() {
2414        LocalTime t = LocalTime.of(11, 30);
2415        assertEquals(t.atOffset(OFFSET_PTWO), OffsetTime.of(LocalTime.of(11, 30), OFFSET_PTWO));
2416    }
2417
2418    @Test(expectedExceptions=NullPointerException.class)
2419    public void test_atOffset_nullZoneOffset() {
2420        LocalTime t = LocalTime.of(11, 30);
2421        t.atOffset((ZoneOffset) null);
2422    }
2423
2424    //-----------------------------------------------------------------------
2425    // toSecondOfDay()
2426    //-----------------------------------------------------------------------
2427    @Test
2428    public void test_toSecondOfDay() {
2429        LocalTime t = LocalTime.of(0, 0);
2430        for (int i = 0; i < 24 * 60 * 60; i++) {
2431            assertEquals(t.toSecondOfDay(), i);
2432            t = t.plusSeconds(1);
2433        }
2434    }
2435
2436    //-----------------------------------------------------------------------
2437    // toEpochSecond()
2438    //--------------------------------------------------------------------------
2439    @DataProvider(name="epochSecond")
2440    Object[][] provider__toEpochSecond() {
2441        return new Object[][] {
2442        {LocalTime.of(0, 0).toEpochSecond(LocalDate.of(1970, 1, 1), OFFSET_PTWO), -7200L},
2443        {LocalTime.of(11, 30).toEpochSecond(LocalDate.of(1965, 12, 31), OFFSET_PTWO), -126282600L},
2444        {LocalTime.of(11, 30).toEpochSecond(LocalDate.of(1995, 5, 3), OFFSET_MTWO), 799507800L},
2445        {LocalTime.of(0, 0).toEpochSecond(LocalDate.of(1970, 1, 1), OFFSET_PTWO),
2446                Instant.ofEpochSecond(-7200).getEpochSecond()},
2447        {LocalTime.of(11, 30).toEpochSecond(LocalDate.of(1969, 12, 31), OFFSET_MTWO),
2448                Instant.ofEpochSecond(-37800L).getEpochSecond()},
2449        {LocalTime.of(11, 30).toEpochSecond(LocalDate.of(1970, 1, 1), OFFSET_PTWO),
2450                LocalDateTime.of(1970, 1, 1, 11, 30).toEpochSecond(OFFSET_PTWO)},
2451        };
2452    }
2453
2454    @Test(dataProvider="epochSecond")
2455    public void test_toEpochSecond(long actual, long expected) {
2456        assertEquals(actual, expected);
2457    }
2458
2459    //-----------------------------------------------------------------------
2460    // toSecondOfDay_fromNanoOfDay_symmetry()
2461    //-----------------------------------------------------------------------
2462    @Test
2463    public void test_toSecondOfDay_fromNanoOfDay_symmetry() {
2464        LocalTime t = LocalTime.of(0, 0);
2465        for (int i = 0; i < 24 * 60 * 60; i++) {
2466            assertEquals(LocalTime.ofSecondOfDay(t.toSecondOfDay()), t);
2467            t = t.plusSeconds(1);
2468        }
2469    }
2470
2471    //-----------------------------------------------------------------------
2472    // toNanoOfDay()
2473    //-----------------------------------------------------------------------
2474    @Test
2475    public void test_toNanoOfDay() {
2476        LocalTime t = LocalTime.of(0, 0);
2477        for (int i = 0; i < 1000000; i++) {
2478            assertEquals(t.toNanoOfDay(), i);
2479            t = t.plusNanos(1);
2480        }
2481        t = LocalTime.of(0, 0);
2482        for (int i = 1; i <= 1000000; i++) {
2483            t = t.minusNanos(1);
2484            assertEquals(t.toNanoOfDay(), 24 * 60 * 60 * 1000000000L - i);
2485        }
2486    }
2487
2488    @Test
2489    public void test_toNanoOfDay_fromNanoOfDay_symmetry() {
2490        LocalTime t = LocalTime.of(0, 0);
2491        for (int i = 0; i < 1000000; i++) {
2492            assertEquals(LocalTime.ofNanoOfDay(t.toNanoOfDay()), t);
2493            t = t.plusNanos(1);
2494        }
2495        t = LocalTime.of(0, 0);
2496        for (int i = 1; i <= 1000000; i++) {
2497            t = t.minusNanos(1);
2498            assertEquals(LocalTime.ofNanoOfDay(t.toNanoOfDay()), t);
2499        }
2500    }
2501
2502    //-----------------------------------------------------------------------
2503    // compareTo()
2504    //-----------------------------------------------------------------------
2505    @Test
2506    public void test_comparisons() {
2507        doTest_comparisons_LocalTime(
2508            LocalTime.MIDNIGHT,
2509            LocalTime.of(0, 0, 0, 999999999),
2510            LocalTime.of(0, 0, 59, 0),
2511            LocalTime.of(0, 0, 59, 999999999),
2512            LocalTime.of(0, 59, 0, 0),
2513            LocalTime.of(0, 59, 0, 999999999),
2514            LocalTime.of(0, 59, 59, 0),
2515            LocalTime.of(0, 59, 59, 999999999),
2516            LocalTime.NOON,
2517            LocalTime.of(12, 0, 0, 999999999),
2518            LocalTime.of(12, 0, 59, 0),
2519            LocalTime.of(12, 0, 59, 999999999),
2520            LocalTime.of(12, 59, 0, 0),
2521            LocalTime.of(12, 59, 0, 999999999),
2522            LocalTime.of(12, 59, 59, 0),
2523            LocalTime.of(12, 59, 59, 999999999),
2524            LocalTime.of(23, 0, 0, 0),
2525            LocalTime.of(23, 0, 0, 999999999),
2526            LocalTime.of(23, 0, 59, 0),
2527            LocalTime.of(23, 0, 59, 999999999),
2528            LocalTime.of(23, 59, 0, 0),
2529            LocalTime.of(23, 59, 0, 999999999),
2530            LocalTime.of(23, 59, 59, 0),
2531            LocalTime.of(23, 59, 59, 999999999)
2532        );
2533    }
2534
2535    void doTest_comparisons_LocalTime(LocalTime... localTimes) {
2536        for (int i = 0; i < localTimes.length; i++) {
2537            LocalTime a = localTimes[i];
2538            for (int j = 0; j < localTimes.length; j++) {
2539                LocalTime b = localTimes[j];
2540                if (i < j) {
2541                    assertTrue(a.compareTo(b) < 0, a + " <=> " + b);
2542                    assertEquals(a.isBefore(b), true, a + " <=> " + b);
2543                    assertEquals(a.isAfter(b), false, a + " <=> " + b);
2544                    assertEquals(a.equals(b), false, a + " <=> " + b);
2545                } else if (i > j) {
2546                    assertTrue(a.compareTo(b) > 0, a + " <=> " + b);
2547                    assertEquals(a.isBefore(b), false, a + " <=> " + b);
2548                    assertEquals(a.isAfter(b), true, a + " <=> " + b);
2549                    assertEquals(a.equals(b), false, a + " <=> " + b);
2550                } else {
2551                    assertEquals(a.compareTo(b), 0, a + " <=> " + b);
2552                    assertEquals(a.isBefore(b), false, a + " <=> " + b);
2553                    assertEquals(a.isAfter(b), false, a + " <=> " + b);
2554                    assertEquals(a.equals(b), true, a + " <=> " + b);
2555                }
2556            }
2557        }
2558    }
2559
2560    @Test(expectedExceptions=NullPointerException.class)
2561    public void test_compareTo_ObjectNull() {
2562        TEST_12_30_40_987654321.compareTo(null);
2563    }
2564
2565    @Test(expectedExceptions=NullPointerException.class)
2566    public void test_isBefore_ObjectNull() {
2567        TEST_12_30_40_987654321.isBefore(null);
2568    }
2569
2570    @Test(expectedExceptions=NullPointerException.class)
2571    public void test_isAfter_ObjectNull() {
2572        TEST_12_30_40_987654321.isAfter(null);
2573    }
2574
2575    @Test(expectedExceptions=ClassCastException.class)
2576    @SuppressWarnings({"unchecked", "rawtypes"})
2577    public void compareToNonLocalTime() {
2578       Comparable c = TEST_12_30_40_987654321;
2579       c.compareTo(new Object());
2580    }
2581
2582    //-----------------------------------------------------------------------
2583    // equals()
2584    //-----------------------------------------------------------------------
2585    @Test(dataProvider="sampleTimes")
2586    public void test_equals_true(int h, int m, int s, int n) {
2587        LocalTime a = LocalTime.of(h, m, s, n);
2588        LocalTime b = LocalTime.of(h, m, s, n);
2589        assertEquals(a.equals(b), true);
2590    }
2591    @Test(dataProvider="sampleTimes")
2592    public void test_equals_false_hour_differs(int h, int m, int s, int n) {
2593        LocalTime a = LocalTime.of(h, m, s, n);
2594        LocalTime b = LocalTime.of(h + 1, m, s, n);
2595        assertEquals(a.equals(b), false);
2596    }
2597    @Test(dataProvider="sampleTimes")
2598    public void test_equals_false_minute_differs(int h, int m, int s, int n) {
2599        LocalTime a = LocalTime.of(h, m, s, n);
2600        LocalTime b = LocalTime.of(h, m + 1, s, n);
2601        assertEquals(a.equals(b), false);
2602    }
2603    @Test(dataProvider="sampleTimes")
2604    public void test_equals_false_second_differs(int h, int m, int s, int n) {
2605        LocalTime a = LocalTime.of(h, m, s, n);
2606        LocalTime b = LocalTime.of(h, m, s + 1, n);
2607        assertEquals(a.equals(b), false);
2608    }
2609    @Test(dataProvider="sampleTimes")
2610    public void test_equals_false_nano_differs(int h, int m, int s, int n) {
2611        LocalTime a = LocalTime.of(h, m, s, n);
2612        LocalTime b = LocalTime.of(h, m, s, n + 1);
2613        assertEquals(a.equals(b), false);
2614    }
2615
2616    @Test
2617    public void test_equals_itself_true() {
2618        assertEquals(TEST_12_30_40_987654321.equals(TEST_12_30_40_987654321), true);
2619    }
2620
2621    @Test
2622    public void test_equals_string_false() {
2623        assertEquals(TEST_12_30_40_987654321.equals("2007-07-15"), false);
2624    }
2625
2626    @Test
2627    public void test_equals_null_false() {
2628        assertEquals(TEST_12_30_40_987654321.equals(null), false);
2629    }
2630
2631    //-----------------------------------------------------------------------
2632    // hashCode()
2633    //-----------------------------------------------------------------------
2634    @Test(dataProvider="sampleTimes")
2635    public void test_hashCode_same(int h, int m, int s, int n) {
2636        LocalTime a = LocalTime.of(h, m, s, n);
2637        LocalTime b = LocalTime.of(h, m, s, n);
2638        assertEquals(a.hashCode(), b.hashCode());
2639    }
2640
2641    @Test(dataProvider="sampleTimes")
2642    public void test_hashCode_hour_differs(int h, int m, int s, int n) {
2643        LocalTime a = LocalTime.of(h, m, s, n);
2644        LocalTime b = LocalTime.of(h + 1, m, s, n);
2645        assertEquals(a.hashCode() == b.hashCode(), false);
2646    }
2647
2648    @Test(dataProvider="sampleTimes")
2649    public void test_hashCode_minute_differs(int h, int m, int s, int n) {
2650        LocalTime a = LocalTime.of(h, m, s, n);
2651        LocalTime b = LocalTime.of(h, m + 1, s, n);
2652        assertEquals(a.hashCode() == b.hashCode(), false);
2653    }
2654
2655    @Test(dataProvider="sampleTimes")
2656    public void test_hashCode_second_differs(int h, int m, int s, int n) {
2657        LocalTime a = LocalTime.of(h, m, s, n);
2658        LocalTime b = LocalTime.of(h, m, s + 1, n);
2659        assertEquals(a.hashCode() == b.hashCode(), false);
2660    }
2661
2662    @Test(dataProvider="sampleTimes")
2663    public void test_hashCode_nano_differs(int h, int m, int s, int n) {
2664        LocalTime a = LocalTime.of(h, m, s, n);
2665        LocalTime b = LocalTime.of(h, m, s, n + 1);
2666        assertEquals(a.hashCode() == b.hashCode(), false);
2667    }
2668
2669    //-----------------------------------------------------------------------
2670    // toString()
2671    //-----------------------------------------------------------------------
2672    @DataProvider(name="sampleToString")
2673    Object[][] provider_sampleToString() {
2674        return new Object[][] {
2675            {0, 0, 0, 0, "00:00"},
2676            {1, 0, 0, 0, "01:00"},
2677            {23, 0, 0, 0, "23:00"},
2678            {0, 1, 0, 0, "00:01"},
2679            {12, 30, 0, 0, "12:30"},
2680            {23, 59, 0, 0, "23:59"},
2681            {0, 0, 1, 0, "00:00:01"},
2682            {0, 0, 59, 0, "00:00:59"},
2683            {0, 0, 0, 100000000, "00:00:00.100"},
2684            {0, 0, 0, 10000000, "00:00:00.010"},
2685            {0, 0, 0, 1000000, "00:00:00.001"},
2686            {0, 0, 0, 100000, "00:00:00.000100"},
2687            {0, 0, 0, 10000, "00:00:00.000010"},
2688            {0, 0, 0, 1000, "00:00:00.000001"},
2689            {0, 0, 0, 100, "00:00:00.000000100"},
2690            {0, 0, 0, 10, "00:00:00.000000010"},
2691            {0, 0, 0, 1, "00:00:00.000000001"},
2692            {0, 0, 0, 999999999, "00:00:00.999999999"},
2693            {0, 0, 0, 99999999, "00:00:00.099999999"},
2694            {0, 0, 0, 9999999, "00:00:00.009999999"},
2695            {0, 0, 0, 999999, "00:00:00.000999999"},
2696            {0, 0, 0, 99999, "00:00:00.000099999"},
2697            {0, 0, 0, 9999, "00:00:00.000009999"},
2698            {0, 0, 0, 999, "00:00:00.000000999"},
2699            {0, 0, 0, 99, "00:00:00.000000099"},
2700            {0, 0, 0, 9, "00:00:00.000000009"},
2701        };
2702    }
2703
2704    @Test(dataProvider="sampleToString")
2705    public void test_toString(int h, int m, int s, int n, String expected) {
2706        LocalTime t = LocalTime.of(h, m, s, n);
2707        String str = t.toString();
2708        assertEquals(str, expected);
2709    }
2710
2711    private LocalTime time(int hour, int min, int sec, int nano) {
2712        return LocalTime.of(hour, min, sec, nano);
2713    }
2714}
2715