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