• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
3  *
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  *  * Redistributions of source code must retain the above copyright notice,
10  *    this list of conditions and the following disclaimer.
11  *
12  *  * Redistributions in binary form must reproduce the above copyright notice,
13  *    this list of conditions and the following disclaimer in the documentation
14  *    and/or other materials provided with the distribution.
15  *
16  *  * Neither the name of JSR-310 nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 package org.threeten.bp;
33 
34 import static org.testng.Assert.assertEquals;
35 import static org.testng.Assert.assertSame;
36 import static org.testng.Assert.assertTrue;
37 
38 import java.io.ByteArrayInputStream;
39 import java.io.ByteArrayOutputStream;
40 import java.io.ObjectInputStream;
41 import java.io.ObjectOutputStream;
42 import java.io.Serializable;
43 
44 import org.testng.annotations.DataProvider;
45 import org.testng.annotations.Test;
46 
47 /**
48  * Test.
49  */
50 @Test
51 public class TestPeriod extends AbstractTest {
52 
53     //-----------------------------------------------------------------------
54     // basics
55     //-----------------------------------------------------------------------
test_interfaces()56     public void test_interfaces() {
57         assertTrue(Serializable.class.isAssignableFrom(Period.class));
58     }
59 
60     @DataProvider(name="serialization")
data_serialization()61     Object[][] data_serialization() {
62         return new Object[][] {
63             {Period.ZERO},
64             {Period.ofDays(1)},
65             {Period.of(1, 2, 3)},
66         };
67     }
68 
69     @Test(dataProvider="serialization")
test_serialization(Period period)70     public void test_serialization(Period period) throws Exception {
71         ByteArrayOutputStream baos = new ByteArrayOutputStream();
72         ObjectOutputStream oos = new ObjectOutputStream(baos);
73         oos.writeObject(period);
74         oos.close();
75 
76         ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(
77                 baos.toByteArray()));
78         if (period.isZero()) {
79             assertSame(ois.readObject(), period);
80         } else {
81             assertEquals(ois.readObject(), period);
82         }
83     }
84 
85     @Test
test_immutable()86     public void test_immutable() {
87         assertImmutable(Period.class);
88     }
89 
90     //-----------------------------------------------------------------------
91     // factories
92     //-----------------------------------------------------------------------
factory_zeroSingleton()93     public void factory_zeroSingleton() {
94         assertSame(Period.ZERO, Period.ZERO);
95         assertSame(Period.of(0, 0, 0), Period.ZERO);
96         assertSame(Period.ofYears(0), Period.ZERO);
97         assertSame(Period.ofMonths(0), Period.ZERO);
98         assertSame(Period.ofDays(0), Period.ZERO);
99     }
100 
101     //-----------------------------------------------------------------------
102     // of
103     //-----------------------------------------------------------------------
factory_of_ints()104     public void factory_of_ints() {
105         assertPeriod(Period.of(1, 2, 3), 1, 2, 3);
106         assertPeriod(Period.of(0, 2, 3), 0, 2, 3);
107         assertPeriod(Period.of(1, 0, 0), 1, 0, 0);
108         assertPeriod(Period.of(0, 0, 0), 0, 0, 0);
109         assertPeriod(Period.of(-1, -2, -3), -1, -2, -3);
110     }
111 
112     //-----------------------------------------------------------------------
factory_ofYears()113     public void factory_ofYears() {
114         assertPeriod(Period.ofYears(1), 1, 0, 0);
115         assertPeriod(Period.ofYears(0), 0, 0, 0);
116         assertPeriod(Period.ofYears(-1), -1, 0, 0);
117         assertPeriod(Period.ofYears(Integer.MAX_VALUE), Integer.MAX_VALUE, 0, 0);
118         assertPeriod(Period.ofYears(Integer.MIN_VALUE), Integer.MIN_VALUE, 0, 0);
119     }
120 
factory_ofMonths()121     public void factory_ofMonths() {
122         assertPeriod(Period.ofMonths(1), 0, 1, 0);
123         assertPeriod(Period.ofMonths(0), 0, 0, 0);
124         assertPeriod(Period.ofMonths(-1), 0, -1, 0);
125         assertPeriod(Period.ofMonths(Integer.MAX_VALUE), 0, Integer.MAX_VALUE, 0);
126         assertPeriod(Period.ofMonths(Integer.MIN_VALUE), 0, Integer.MIN_VALUE, 0);
127     }
128 
factory_ofDays()129     public void factory_ofDays() {
130         assertPeriod(Period.ofDays(1), 0, 0, 1);
131         assertPeriod(Period.ofDays(0), 0, 0, 0);
132         assertPeriod(Period.ofDays(-1), 0, 0, -1);
133         assertPeriod(Period.ofDays(Integer.MAX_VALUE), 0, 0, Integer.MAX_VALUE);
134         assertPeriod(Period.ofDays(Integer.MIN_VALUE), 0, 0, Integer.MIN_VALUE);
135     }
136 
137     //-----------------------------------------------------------------------
138     // between
139     //-----------------------------------------------------------------------
140     @DataProvider(name="between")
data_between()141     Object[][] data_between() {
142         return new Object[][] {
143             {2010, 1, 1, 2010, 1, 1, 0, 0, 0},
144             {2010, 1, 1, 2010, 1, 2, 0, 0, 1},
145             {2010, 1, 1, 2010, 1, 31, 0, 0, 30},
146             {2010, 1, 1, 2010, 2, 1, 0, 1, 0},
147             {2010, 1, 1, 2010, 2, 28, 0, 1, 27},
148             {2010, 1, 1, 2010, 3, 1, 0, 2, 0},
149             {2010, 1, 1, 2010, 12, 31, 0, 11, 30},
150             {2010, 1, 1, 2011, 1, 1, 1, 0, 0},
151             {2010, 1, 1, 2011, 12, 31, 1, 11, 30},
152             {2010, 1, 1, 2012, 1, 1, 2, 0, 0},
153 
154             {2010, 1, 10, 2010, 1, 1, 0, 0, -9},
155             {2010, 1, 10, 2010, 1, 2, 0, 0, -8},
156             {2010, 1, 10, 2010, 1, 9, 0, 0, -1},
157             {2010, 1, 10, 2010, 1, 10, 0, 0, 0},
158             {2010, 1, 10, 2010, 1, 11, 0, 0, 1},
159             {2010, 1, 10, 2010, 1, 31, 0, 0, 21},
160             {2010, 1, 10, 2010, 2, 1, 0, 0, 22},
161             {2010, 1, 10, 2010, 2, 9, 0, 0, 30},
162             {2010, 1, 10, 2010, 2, 10, 0, 1, 0},
163             {2010, 1, 10, 2010, 2, 28, 0, 1, 18},
164             {2010, 1, 10, 2010, 3, 1, 0, 1, 19},
165             {2010, 1, 10, 2010, 3, 9, 0, 1, 27},
166             {2010, 1, 10, 2010, 3, 10, 0, 2, 0},
167             {2010, 1, 10, 2010, 12, 31, 0, 11, 21},
168             {2010, 1, 10, 2011, 1, 1, 0, 11, 22},
169             {2010, 1, 10, 2011, 1, 9, 0, 11, 30},
170             {2010, 1, 10, 2011, 1, 10, 1, 0, 0},
171 
172             {2010, 3, 30, 2011, 5, 1, 1, 1, 1},
173             {2010, 4, 30, 2011, 5, 1, 1, 0, 1},
174 
175             {2010, 2, 28, 2012, 2, 27, 1, 11, 30},
176             {2010, 2, 28, 2012, 2, 28, 2, 0, 0},
177             {2010, 2, 28, 2012, 2, 29, 2, 0, 1},
178 
179             {2012, 2, 28, 2014, 2, 27, 1, 11, 30},
180             {2012, 2, 28, 2014, 2, 28, 2, 0, 0},
181             {2012, 2, 28, 2014, 3, 1, 2, 0, 1},
182 
183             {2012, 2, 29, 2014, 2, 28, 1, 11, 30},
184             {2012, 2, 29, 2014, 3, 1, 2, 0, 1},
185             {2012, 2, 29, 2014, 3, 2, 2, 0, 2},
186 
187             {2012, 2, 29, 2016, 2, 28, 3, 11, 30},
188             {2012, 2, 29, 2016, 2, 29, 4, 0, 0},
189             {2012, 2, 29, 2016, 3, 1, 4, 0, 1},
190 
191             {2010, 1, 1, 2009, 12, 31, 0, 0, -1},
192             {2010, 1, 1, 2009, 12, 30, 0, 0, -2},
193             {2010, 1, 1, 2009, 12, 2, 0, 0, -30},
194             {2010, 1, 1, 2009, 12, 1, 0, -1, 0},
195             {2010, 1, 1, 2009, 11, 30, 0, -1, -1},
196             {2010, 1, 1, 2009, 11, 2, 0, -1, -29},
197             {2010, 1, 1, 2009, 11, 1, 0, -2, 0},
198             {2010, 1, 1, 2009, 1, 2, 0, -11, -30},
199             {2010, 1, 1, 2009, 1, 1, -1, 0, 0},
200 
201             {2010, 1, 15, 2010, 1, 15, 0, 0, 0},
202             {2010, 1, 15, 2010, 1, 14, 0, 0, -1},
203             {2010, 1, 15, 2010, 1, 1, 0, 0, -14},
204             {2010, 1, 15, 2009, 12, 31, 0, 0, -15},
205             {2010, 1, 15, 2009, 12, 16, 0, 0, -30},
206             {2010, 1, 15, 2009, 12, 15, 0, -1, 0},
207             {2010, 1, 15, 2009, 12, 14, 0, -1, -1},
208 
209             {2010, 2, 28, 2009, 3, 1, 0, -11, -27},
210             {2010, 2, 28, 2009, 2, 28, -1, 0, 0},
211             {2010, 2, 28, 2009, 2, 27, -1, 0, -1},
212 
213             {2010, 2, 28, 2008, 2, 29, -1, -11, -28},
214             {2010, 2, 28, 2008, 2, 28, -2, 0, 0},
215             {2010, 2, 28, 2008, 2, 27, -2, 0, -1},
216 
217             {2012, 2, 29, 2009, 3, 1, -2, -11, -28},
218             {2012, 2, 29, 2009, 2, 28, -3, 0, -1},
219             {2012, 2, 29, 2009, 2, 27, -3, 0, -2},
220 
221             {2012, 2, 29, 2008, 3, 1, -3, -11, -28},
222             {2012, 2, 29, 2008, 2, 29, -4, 0, 0},
223             {2012, 2, 29, 2008, 2, 28, -4, 0, -1},
224         };
225     }
226 
227     @Test(dataProvider="between")
factory_between_LocalDate(int y1, int m1, int d1, int y2, int m2, int d2, int ye, int me, int de)228     public void factory_between_LocalDate(int y1, int m1, int d1, int y2, int m2, int d2, int ye, int me, int de) {
229         LocalDate start = LocalDate.of(y1, m1, d1);
230         LocalDate end = LocalDate.of(y2, m2, d2);
231         Period test = Period.between(start, end);
232         assertPeriod(test, ye, me, de);
233         //assertEquals(start.plus(test), end);
234     }
235 
236     @Test(expectedExceptions=NullPointerException.class)
factory_between_LocalDate_nullFirst()237     public void factory_between_LocalDate_nullFirst() {
238         Period.between((LocalDate) null, LocalDate.of(2010, 1, 1));
239     }
240 
241     @Test(expectedExceptions=NullPointerException.class)
factory_between_LocalDate_nullSecond()242     public void factory_between_LocalDate_nullSecond() {
243         Period.between(LocalDate.of(2010, 1, 1), (LocalDate) null);
244     }
245 
246     //-----------------------------------------------------------------------
247     // parse()
248     //-----------------------------------------------------------------------
249     @DataProvider(name="parse")
data_parse()250     Object[][] data_parse() {
251         return new Object[][] {
252             {"P0D", Period.ZERO},
253             {"P0W", Period.ZERO},
254             {"P0M", Period.ZERO},
255             {"P0Y", Period.ZERO},
256 
257             {"P0Y0D", Period.ZERO},
258             {"P0Y0W", Period.ZERO},
259             {"P0Y0M", Period.ZERO},
260             {"P0M0D", Period.ZERO},
261             {"P0M0W", Period.ZERO},
262             {"P0W0D", Period.ZERO},
263 
264             {"P1D", Period.ofDays(1)},
265             {"P2D", Period.ofDays(2)},
266             {"P-2D", Period.ofDays(-2)},
267             {"-P2D", Period.ofDays(-2)},
268             {"-P-2D", Period.ofDays(2)},
269             {"P" + Integer.MAX_VALUE + "D", Period.ofDays(Integer.MAX_VALUE)},
270             {"P" + Integer.MIN_VALUE + "D", Period.ofDays(Integer.MIN_VALUE)},
271 
272             {"P1W", Period.ofDays(7)},
273             {"P2W", Period.ofDays(14)},
274             {"P-2W", Period.ofDays(-14)},
275             {"-P2W", Period.ofDays(-14)},
276             {"-P-2W", Period.ofDays(14)},
277 
278             {"P1M", Period.ofMonths(1)},
279             {"P2M", Period.ofMonths(2)},
280             {"P-2M", Period.ofMonths(-2)},
281             {"-P2M", Period.ofMonths(-2)},
282             {"-P-2M", Period.ofMonths(2)},
283             {"P" + Integer.MAX_VALUE + "M", Period.ofMonths(Integer.MAX_VALUE)},
284             {"P" + Integer.MIN_VALUE + "M", Period.ofMonths(Integer.MIN_VALUE)},
285 
286             {"P1Y", Period.ofYears(1)},
287             {"P2Y", Period.ofYears(2)},
288             {"P-2Y", Period.ofYears(-2)},
289             {"-P2Y", Period.ofYears(-2)},
290             {"-P-2Y", Period.ofYears(2)},
291             {"P" + Integer.MAX_VALUE + "Y", Period.ofYears(Integer.MAX_VALUE)},
292             {"P" + Integer.MIN_VALUE + "Y", Period.ofYears(Integer.MIN_VALUE)},
293 
294             {"P1Y2M3W4D", Period.of(1, 2, 3 * 7 + 4)},
295         };
296     }
297 
298     @Test(dataProvider="parse")
test_parse(String text, Period expected)299     public void test_parse(String text, Period expected) {
300         assertEquals(Period.parse(text), expected);
301     }
302 
303     @Test(dataProvider="toStringAndParse")
test_parse_toString(Period test, String expected)304     public void test_parse_toString(Period test, String expected) {
305         assertEquals(test, Period.parse(expected));
306     }
307 
308     @Test(expectedExceptions=NullPointerException.class)
test_parse_nullText()309     public void test_parse_nullText() {
310         Period.parse((String) null);
311     }
312 
313     //-----------------------------------------------------------------------
314     // isZero()
315     //-----------------------------------------------------------------------
test_isZero()316     public void test_isZero() {
317         assertEquals(Period.of(1, 2, 3).isZero(), false);
318         assertEquals(Period.of(1, 0, 0).isZero(), false);
319         assertEquals(Period.of(0, 2, 0).isZero(), false);
320         assertEquals(Period.of(0, 0, 3).isZero(), false);
321         assertEquals(Period.of(0, 0, 0).isZero(), true);
322     }
323 
324     //-----------------------------------------------------------------------
325     // isNegative()
326     //-----------------------------------------------------------------------
test_isNegative()327     public void test_isNegative() {
328         assertEquals(Period.of(0, 0, 0).isNegative(), false);
329 
330         assertEquals(Period.of(1, 2, 3).isNegative(), false);
331         assertEquals(Period.of(1, 0, 0).isNegative(), false);
332         assertEquals(Period.of(0, 2, 0).isNegative(), false);
333         assertEquals(Period.of(0, 0, 3).isNegative(), false);
334 
335         assertEquals(Period.of(-1, -2, -3).isNegative(), true);
336         assertEquals(Period.of(-1, 0, 0).isNegative(), true);
337         assertEquals(Period.of(0, -2, 0).isNegative(), true);
338         assertEquals(Period.of(0, 0, -3).isNegative(), true);
339         assertEquals(Period.of(-1, 2, 3).isNegative(), true);
340         assertEquals(Period.of(1, -2, 3).isNegative(), true);
341         assertEquals(Period.of(1, 2, -3).isNegative(), true);
342     }
343 
344     //-----------------------------------------------------------------------
345     // withYears()
346     //-----------------------------------------------------------------------
test_withYears()347     public void test_withYears() {
348         Period test = Period.of(1, 2, 3);
349         assertPeriod(test.withYears(10), 10, 2, 3);
350     }
351 
test_withYears_noChange()352     public void test_withYears_noChange() {
353         Period test = Period.of(1, 2, 3);
354         assertSame(test.withYears(1), test);
355     }
356 
test_withYears_toZero()357     public void test_withYears_toZero() {
358         Period test = Period.ofYears(1);
359         assertSame(test.withYears(0), Period.ZERO);
360     }
361 
362     //-----------------------------------------------------------------------
363     // withMonths()
364     //-----------------------------------------------------------------------
test_withMonths()365     public void test_withMonths() {
366         Period test = Period.of(1, 2, 3);
367         assertPeriod(test.withMonths(10), 1, 10, 3);
368     }
369 
test_withMonths_noChange()370     public void test_withMonths_noChange() {
371         Period test = Period.of(1, 2, 3);
372         assertSame(test.withMonths(2), test);
373     }
374 
test_withMonths_toZero()375     public void test_withMonths_toZero() {
376         Period test = Period.ofMonths(1);
377         assertSame(test.withMonths(0), Period.ZERO);
378     }
379 
380     //-----------------------------------------------------------------------
381     // withDays()
382     //-----------------------------------------------------------------------
test_withDays()383     public void test_withDays() {
384         Period test = Period.of(1, 2, 3);
385         assertPeriod(test.withDays(10), 1, 2, 10);
386     }
387 
test_withDays_noChange()388     public void test_withDays_noChange() {
389         Period test = Period.of(1, 2, 3);
390         assertSame(test.withDays(3), test);
391     }
392 
test_withDays_toZero()393     public void test_withDays_toZero() {
394         Period test = Period.ofDays(1);
395         assertSame(test.withDays(0), Period.ZERO);
396     }
397 
398     //-----------------------------------------------------------------------
399     // plus(Period)
400     //-----------------------------------------------------------------------
401     @DataProvider(name="plus")
data_plus()402     Object[][] data_plus() {
403         return new Object[][] {
404             {pymd(0, 0, 0), pymd(0, 0, 0), pymd(0, 0, 0)},
405             {pymd(0, 0, 0), pymd(5, 0, 0), pymd(5, 0, 0)},
406             {pymd(0, 0, 0), pymd(-5, 0, 0), pymd(-5, 0, 0)},
407             {pymd(0, 0, 0), pymd(0, 5, 0), pymd(0, 5, 0)},
408             {pymd(0, 0, 0), pymd(0, -5, 0), pymd(0, -5, 0)},
409             {pymd(0, 0, 0), pymd(0, 0, 5), pymd(0, 0, 5)},
410             {pymd(0, 0, 0), pymd(0, 0, -5), pymd(0, 0, -5)},
411             {pymd(0, 0, 0), pymd(2, 3, 4), pymd(2, 3, 4)},
412             {pymd(0, 0, 0), pymd(-2, -3, -4), pymd(-2, -3, -4)},
413 
414             {pymd(4, 5, 6), pymd(2, 3, 4), pymd(6, 8, 10)},
415             {pymd(4, 5, 6), pymd(-2, -3, -4), pymd(2, 2, 2)},
416         };
417     }
418 
419     @Test(dataProvider="plus")
test_plus(Period base, Period add, Period expected)420     public void test_plus(Period base, Period add, Period expected) {
421         assertEquals(base.plus(add), expected);
422     }
423 
424     //-----------------------------------------------------------------------
425     // plusYears()
426     //-----------------------------------------------------------------------
test_plusYears()427     public void test_plusYears() {
428         Period test = Period.of(1, 2, 3);
429         assertPeriod(test.plusYears(10), 11, 2, 3);
430         assertPeriod(test.plus(Period.ofYears(10)), 11, 2, 3);
431     }
432 
test_plusYears_noChange()433     public void test_plusYears_noChange() {
434         Period test = Period.of(1, 2, 3);
435         assertSame(test.plusYears(0), test);
436         assertPeriod(test.plus(Period.ofYears(0)), 1, 2, 3);
437     }
438 
test_plusYears_toZero()439     public void test_plusYears_toZero() {
440         Period test = Period.ofYears(-1);
441         assertSame(test.plusYears(1), Period.ZERO);
442         assertSame(test.plus(Period.ofYears(1)), Period.ZERO);
443     }
444 
445     @Test(expectedExceptions=ArithmeticException.class)
test_plusYears_overflowTooBig()446     public void test_plusYears_overflowTooBig() {
447         Period test = Period.ofYears(Integer.MAX_VALUE);
448         test.plusYears(1);
449     }
450 
451     @Test(expectedExceptions=ArithmeticException.class)
test_plusYears_overflowTooSmall()452     public void test_plusYears_overflowTooSmall() {
453         Period test = Period.ofYears(Integer.MIN_VALUE);
454         test.plusYears(-1);
455     }
456 
457     //-----------------------------------------------------------------------
458     // plusMonths()
459     //-----------------------------------------------------------------------
test_plusMonths()460     public void test_plusMonths() {
461         Period test = Period.of(1, 2, 3);
462         assertPeriod(test.plusMonths(10), 1, 12, 3);
463         assertPeriod(test.plus(Period.ofMonths(10)), 1, 12, 3);
464     }
465 
test_plusMonths_noChange()466     public void test_plusMonths_noChange() {
467         Period test = Period.of(1, 2, 3);
468         assertSame(test.plusMonths(0), test);
469         assertEquals(test.plus(Period.ofMonths(0)), test);
470     }
471 
test_plusMonths_toZero()472     public void test_plusMonths_toZero() {
473         Period test = Period.ofMonths(-1);
474         assertSame(test.plusMonths(1), Period.ZERO);
475         assertSame(test.plus(Period.ofMonths(1)), Period.ZERO);
476     }
477 
478     @Test(expectedExceptions=ArithmeticException.class)
test_plusMonths_overflowTooBig()479     public void test_plusMonths_overflowTooBig() {
480         Period test = Period.ofMonths(Integer.MAX_VALUE);
481         test.plusMonths(1);
482     }
483 
484     @Test(expectedExceptions=ArithmeticException.class)
test_plusMonths_overflowTooSmall()485     public void test_plusMonths_overflowTooSmall() {
486         Period test = Period.ofMonths(Integer.MIN_VALUE);
487         test.plusMonths(-1);
488     }
489 
490     //-----------------------------------------------------------------------
491     // plusDays()
492     //-----------------------------------------------------------------------
test_plusDays()493     public void test_plusDays() {
494         Period test = Period.of(1, 2, 3);
495         assertPeriod(test.plusDays(10), 1, 2, 13);
496     }
497 
test_plusDays_noChange()498     public void test_plusDays_noChange() {
499         Period test = Period.of(1, 2, 3);
500         assertSame(test.plusDays(0), test);
501     }
502 
test_plusDays_toZero()503     public void test_plusDays_toZero() {
504         Period test = Period.ofDays(-1);
505         assertSame(test.plusDays(1), Period.ZERO);
506     }
507 
508     @Test(expectedExceptions=ArithmeticException.class)
test_plusDays_overflowTooBig()509     public void test_plusDays_overflowTooBig() {
510         Period test = Period.ofDays(Integer.MAX_VALUE);
511         test.plusDays(1);
512     }
513 
514     @Test(expectedExceptions=ArithmeticException.class)
test_plusDays_overflowTooSmall()515     public void test_plusDays_overflowTooSmall() {
516         Period test = Period.ofDays(Integer.MIN_VALUE);
517         test.plusDays(-1);
518     }
519 
520     //-----------------------------------------------------------------------
521     // minus(Period)
522     //-----------------------------------------------------------------------
523     @DataProvider(name="minus")
data_minus()524     Object[][] data_minus() {
525         return new Object[][] {
526             {pymd(0, 0, 0), pymd(0, 0, 0), pymd(0, 0, 0)},
527             {pymd(0, 0, 0), pymd(5, 0, 0), pymd(-5, 0, 0)},
528             {pymd(0, 0, 0), pymd(-5, 0, 0), pymd(5, 0, 0)},
529             {pymd(0, 0, 0), pymd(0, 5, 0), pymd(0, -5, 0)},
530             {pymd(0, 0, 0), pymd(0, -5, 0), pymd(0, 5, 0)},
531             {pymd(0, 0, 0), pymd(0, 0, 5), pymd(0, 0, -5)},
532             {pymd(0, 0, 0), pymd(0, 0, -5), pymd(0, 0, 5)},
533             {pymd(0, 0, 0), pymd(2, 3, 4), pymd(-2, -3, -4)},
534             {pymd(0, 0, 0), pymd(-2, -3, -4), pymd(2, 3, 4)},
535 
536             {pymd(4, 5, 6), pymd(2, 3, 4), pymd(2, 2, 2)},
537             {pymd(4, 5, 6), pymd(-2, -3, -4), pymd(6, 8, 10)},
538         };
539     }
540 
541     @Test(dataProvider="minus")
test_minus(Period base, Period subtract, Period expected)542     public void test_minus(Period base, Period subtract, Period expected) {
543         assertEquals(base.minus(subtract), expected);
544     }
545 
546     //-----------------------------------------------------------------------
547     // minusYears()
548     //-----------------------------------------------------------------------
test_minusYears()549     public void test_minusYears() {
550         Period test = Period.of(1, 2, 3);
551         assertPeriod(test.minusYears(10), -9, 2, 3);
552     }
553 
test_minusYears_noChange()554     public void test_minusYears_noChange() {
555         Period test = Period.of(1, 2, 3);
556         assertSame(test.minusYears(0), test);
557     }
558 
test_minusYears_toZero()559     public void test_minusYears_toZero() {
560         Period test = Period.ofYears(1);
561         assertSame(test.minusYears(1), Period.ZERO);
562     }
563 
564     @Test(expectedExceptions=ArithmeticException.class)
test_minusYears_overflowTooBig()565     public void test_minusYears_overflowTooBig() {
566         Period test = Period.ofYears(Integer.MAX_VALUE);
567         test.minusYears(-1);
568     }
569 
570     @Test(expectedExceptions=ArithmeticException.class)
test_minusYears_overflowTooSmall()571     public void test_minusYears_overflowTooSmall() {
572         Period test = Period.ofYears(Integer.MIN_VALUE);
573         test.minusYears(1);
574     }
575 
576     //-----------------------------------------------------------------------
577     // minusMonths()
578     //-----------------------------------------------------------------------
test_minusMonths()579     public void test_minusMonths() {
580         Period test = Period.of(1, 2, 3);
581         assertPeriod(test.minusMonths(10), 1, -8, 3);
582     }
583 
test_minusMonths_noChange()584     public void test_minusMonths_noChange() {
585         Period test = Period.of(1, 2, 3);
586         assertSame(test.minusMonths(0), test);
587     }
588 
test_minusMonths_toZero()589     public void test_minusMonths_toZero() {
590         Period test = Period.ofMonths(1);
591         assertSame(test.minusMonths(1), Period.ZERO);
592     }
593 
594     @Test(expectedExceptions=ArithmeticException.class)
test_minusMonths_overflowTooBig()595     public void test_minusMonths_overflowTooBig() {
596         Period test = Period.ofMonths(Integer.MAX_VALUE);
597         test.minusMonths(-1);
598     }
599 
600     @Test(expectedExceptions=ArithmeticException.class)
test_minusMonths_overflowTooSmall()601     public void test_minusMonths_overflowTooSmall() {
602         Period test = Period.ofMonths(Integer.MIN_VALUE);
603         test.minusMonths(1);
604     }
605 
606     //-----------------------------------------------------------------------
607     // minusDays()
608     //-----------------------------------------------------------------------
test_minusDays()609     public void test_minusDays() {
610         Period test = Period.of(1, 2, 3);
611         assertPeriod(test.minusDays(10), 1, 2, -7);
612     }
613 
test_minusDays_noChange()614     public void test_minusDays_noChange() {
615         Period test = Period.of(1, 2, 3);
616         assertSame(test.minusDays(0), test);
617     }
618 
test_minusDays_toZero()619     public void test_minusDays_toZero() {
620         Period test = Period.ofDays(1);
621         assertSame(test.minusDays(1), Period.ZERO);
622     }
623 
624     @Test(expectedExceptions=ArithmeticException.class)
test_minusDays_overflowTooBig()625     public void test_minusDays_overflowTooBig() {
626         Period test = Period.ofDays(Integer.MAX_VALUE);
627         test.minusDays(-1);
628     }
629 
630     @Test(expectedExceptions=ArithmeticException.class)
test_minusDays_overflowTooSmall()631     public void test_minusDays_overflowTooSmall() {
632         Period test = Period.ofDays(Integer.MIN_VALUE);
633         test.minusDays(1);
634     }
635 
636     //-----------------------------------------------------------------------
637     // multipliedBy()
638     //-----------------------------------------------------------------------
test_multipliedBy()639     public void test_multipliedBy() {
640         Period test = Period.of(1, 2, 3);
641         assertPeriod(test.multipliedBy(2), 2, 4, 6);
642         assertPeriod(test.multipliedBy(-3), -3, -6, -9);
643     }
644 
test_multipliedBy_zeroBase()645     public void test_multipliedBy_zeroBase() {
646         assertSame(Period.ZERO.multipliedBy(2), Period.ZERO);
647     }
648 
test_multipliedBy_zero()649     public void test_multipliedBy_zero() {
650         Period test = Period.of(1, 2, 3);
651         assertSame(test.multipliedBy(0), Period.ZERO);
652     }
653 
test_multipliedBy_one()654     public void test_multipliedBy_one() {
655         Period test = Period.of(1, 2, 3);
656         assertSame(test.multipliedBy(1), test);
657     }
658 
659     @Test(expectedExceptions=ArithmeticException.class)
test_multipliedBy_overflowTooBig()660     public void test_multipliedBy_overflowTooBig() {
661         Period test = Period.ofYears(Integer.MAX_VALUE / 2 + 1);
662         test.multipliedBy(2);
663     }
664 
665     @Test(expectedExceptions=ArithmeticException.class)
test_multipliedBy_overflowTooSmall()666     public void test_multipliedBy_overflowTooSmall() {
667         Period test = Period.ofYears(Integer.MIN_VALUE / 2 - 1);
668         test.multipliedBy(2);
669     }
670 
671     //-----------------------------------------------------------------------
672     // negated()
673     //-----------------------------------------------------------------------
test_negated()674     public void test_negated() {
675         Period test = Period.of(1, 2, 3);
676         assertPeriod(test.negated(), -1, -2, -3);
677     }
678 
test_negated_zero()679     public void test_negated_zero() {
680         assertSame(Period.ZERO.negated(), Period.ZERO);
681     }
682 
test_negated_max()683     public void test_negated_max() {
684         assertPeriod(Period.ofYears(Integer.MAX_VALUE).negated(), -Integer.MAX_VALUE, 0, 0);
685     }
686 
687     @Test(expectedExceptions=ArithmeticException.class)
test_negated_overflow()688     public void test_negated_overflow() {
689         Period.ofYears(Integer.MIN_VALUE).negated();
690     }
691 
692     //-----------------------------------------------------------------------
693     // normalized()
694     //-----------------------------------------------------------------------
695     @DataProvider(name="normalized")
data_normalized()696     Object[][] data_normalized() {
697         return new Object[][] {
698             {0, 0,  0, 0},
699             {1, 0,  1, 0},
700             {-1, 0,  -1, 0},
701 
702             {1, 1,  1, 1},
703             {1, 2,  1, 2},
704             {1, 11,  1, 11},
705             {1, 12,  2, 0},
706             {1, 13,  2, 1},
707             {1, 23,  2, 11},
708             {1, 24,  3, 0},
709             {1, 25,  3, 1},
710 
711             {1, -1,  0, 11},
712             {1, -2,  0, 10},
713             {1, -11,  0, 1},
714             {1, -12,  0, 0},
715             {1, -13,  0, -1},
716             {1, -23,  0, -11},
717             {1, -24,  -1, 0},
718             {1, -25,  -1, -1},
719             {1, -35,  -1, -11},
720             {1, -36,  -2, 0},
721             {1, -37,  -2, -1},
722 
723             {-1, 1,  0, -11},
724             {-1, 11,  0, -1},
725             {-1, 12,  0, 0},
726             {-1, 13,  0, 1},
727             {-1, 23,  0, 11},
728             {-1, 24,  1, 0},
729             {-1, 25,  1, 1},
730 
731             {-1, -1,  -1, -1},
732             {-1, -11,  -1, -11},
733             {-1, -12,  -2, 0},
734             {-1, -13,  -2, -1},
735         };
736     }
737 
738     @Test(dataProvider="normalized")
test_normalized(int inputYears, int inputMonths, int expectedYears, int expectedMonths)739     public void test_normalized(int inputYears, int inputMonths, int expectedYears, int expectedMonths) {
740         assertPeriod(Period.of(inputYears, inputMonths, 0).normalized(), expectedYears, expectedMonths, 0);
741     }
742 
743     @Test(expectedExceptions=ArithmeticException.class)
test_normalizedMonthsISO_min()744     public void test_normalizedMonthsISO_min() {
745         Period base = Period.of(Integer.MIN_VALUE, -12, 0);
746         base.normalized();
747     }
748 
749     @Test(expectedExceptions=ArithmeticException.class)
test_normalizedMonthsISO_max()750     public void test_normalizedMonthsISO_max() {
751         Period base = Period.of(Integer.MAX_VALUE, 12, 0);
752         base.normalized();
753     }
754 
755     //-----------------------------------------------------------------------
756     // addTo()
757     //-----------------------------------------------------------------------
758     @DataProvider(name="addTo")
data_addTo()759     Object[][] data_addTo() {
760         return new Object[][] {
761             {pymd(0, 0, 0),  date(2012, 6, 30), date(2012, 6, 30)},
762 
763             {pymd(1, 0, 0),  date(2012, 6, 10), date(2013, 6, 10)},
764             {pymd(0, 1, 0),  date(2012, 6, 10), date(2012, 7, 10)},
765             {pymd(0, 0, 1),  date(2012, 6, 10), date(2012, 6, 11)},
766 
767             {pymd(-1, 0, 0),  date(2012, 6, 10), date(2011, 6, 10)},
768             {pymd(0, -1, 0),  date(2012, 6, 10), date(2012, 5, 10)},
769             {pymd(0, 0, -1),  date(2012, 6, 10), date(2012, 6, 9)},
770 
771             {pymd(1, 2, 3),  date(2012, 6, 27), date(2013, 8, 30)},
772             {pymd(1, 2, 3),  date(2012, 6, 28), date(2013, 8, 31)},
773             {pymd(1, 2, 3),  date(2012, 6, 29), date(2013, 9, 1)},
774             {pymd(1, 2, 3),  date(2012, 6, 30), date(2013, 9, 2)},
775             {pymd(1, 2, 3),  date(2012, 7, 1), date(2013, 9, 4)},
776 
777             {pymd(1, 0, 0),  date(2011, 2, 28), date(2012, 2, 28)},
778             {pymd(4, 0, 0),  date(2011, 2, 28), date(2015, 2, 28)},
779             {pymd(1, 0, 0),  date(2012, 2, 29), date(2013, 2, 28)},
780             {pymd(4, 0, 0),  date(2012, 2, 29), date(2016, 2, 29)},
781 
782             {pymd(1, 1, 0),  date(2011, 1, 29), date(2012, 2, 29)},
783             {pymd(1, 2, 0),  date(2012, 2, 29), date(2013, 4, 29)},
784         };
785     }
786 
787     @Test(dataProvider="addTo")
test_addTo(Period period, LocalDate baseDate, LocalDate expected)788     public void test_addTo(Period period, LocalDate baseDate, LocalDate expected) {
789         assertEquals(period.addTo(baseDate), expected);
790     }
791 
792     @Test(dataProvider="addTo")
test_addTo_usingLocalDatePlus(Period period, LocalDate baseDate, LocalDate expected)793     public void test_addTo_usingLocalDatePlus(Period period, LocalDate baseDate, LocalDate expected) {
794         assertEquals(baseDate.plus(period), expected);
795     }
796 
797     @Test(expectedExceptions=NullPointerException.class)
test_addTo_nullZero()798     public void test_addTo_nullZero() {
799         Period.ZERO.addTo(null);
800     }
801 
802     @Test(expectedExceptions=NullPointerException.class)
test_addTo_nullNonZero()803     public void test_addTo_nullNonZero() {
804         Period.ofDays(2).addTo(null);
805     }
806 
807     //-----------------------------------------------------------------------
808     // subtractFrom()
809     //-----------------------------------------------------------------------
810     @DataProvider(name="subtractFrom")
data_subtractFrom()811     Object[][] data_subtractFrom() {
812         return new Object[][] {
813             {pymd(0, 0, 0),  date(2012, 6, 30), date(2012, 6, 30)},
814 
815             {pymd(1, 0, 0),  date(2012, 6, 10), date(2011, 6, 10)},
816             {pymd(0, 1, 0),  date(2012, 6, 10), date(2012, 5, 10)},
817             {pymd(0, 0, 1),  date(2012, 6, 10), date(2012, 6, 9)},
818 
819             {pymd(-1, 0, 0),  date(2012, 6, 10), date(2013, 6, 10)},
820             {pymd(0, -1, 0),  date(2012, 6, 10), date(2012, 7, 10)},
821             {pymd(0, 0, -1),  date(2012, 6, 10), date(2012, 6, 11)},
822 
823             {pymd(1, 2, 3),  date(2012, 8, 30), date(2011, 6, 27)},
824             {pymd(1, 2, 3),  date(2012, 8, 31), date(2011, 6, 27)},
825             {pymd(1, 2, 3),  date(2012, 9, 1), date(2011, 6, 28)},
826             {pymd(1, 2, 3),  date(2012, 9, 2), date(2011, 6, 29)},
827             {pymd(1, 2, 3),  date(2012, 9, 3), date(2011, 6, 30)},
828             {pymd(1, 2, 3),  date(2012, 9, 4), date(2011, 7, 1)},
829 
830             {pymd(1, 0, 0),  date(2011, 2, 28), date(2010, 2, 28)},
831             {pymd(4, 0, 0),  date(2011, 2, 28), date(2007, 2, 28)},
832             {pymd(1, 0, 0),  date(2012, 2, 29), date(2011, 2, 28)},
833             {pymd(4, 0, 0),  date(2012, 2, 29), date(2008, 2, 29)},
834 
835             {pymd(1, 1, 0),  date(2013, 3, 29), date(2012, 2, 29)},
836             {pymd(1, 2, 0),  date(2012, 2, 29), date(2010, 12, 29)},
837         };
838     }
839 
840     @Test(dataProvider="subtractFrom")
test_subtractFrom(Period period, LocalDate baseDate, LocalDate expected)841     public void test_subtractFrom(Period period, LocalDate baseDate, LocalDate expected) {
842         assertEquals(period.subtractFrom(baseDate), expected);
843     }
844 
845     @Test(dataProvider="subtractFrom")
test_subtractFrom_usingLocalDateMinus(Period period, LocalDate baseDate, LocalDate expected)846     public void test_subtractFrom_usingLocalDateMinus(Period period, LocalDate baseDate, LocalDate expected) {
847         assertEquals(baseDate.minus(period), expected);
848     }
849 
850     @Test(expectedExceptions=NullPointerException.class)
test_subtractFrom_nullZero()851     public void test_subtractFrom_nullZero() {
852         Period.ZERO.subtractFrom(null);
853     }
854 
855     @Test(expectedExceptions=NullPointerException.class)
test_subtractFrom_nullNonZero()856     public void test_subtractFrom_nullNonZero() {
857         Period.ofDays(2).subtractFrom(null);
858     }
859 
860     //-----------------------------------------------------------------------
861     // equals() / hashCode()
862     //-----------------------------------------------------------------------
test_equals()863     public void test_equals() {
864         assertEquals(Period.of(1, 0, 0).equals(Period.ofYears(1)), true);
865         assertEquals(Period.of(0, 1, 0).equals(Period.ofMonths(1)), true);
866         assertEquals(Period.of(0, 0, 1).equals(Period.ofDays(1)), true);
867         assertEquals(Period.of(1, 2, 3).equals(Period.of(1, 2, 3)), true);
868 
869         assertEquals(Period.ofYears(1).equals(Period.ofYears(1)), true);
870         assertEquals(Period.ofYears(1).equals(Period.ofYears(2)), false);
871 
872         assertEquals(Period.ofMonths(1).equals(Period.ofMonths(1)), true);
873         assertEquals(Period.ofMonths(1).equals(Period.ofMonths(2)), false);
874 
875         assertEquals(Period.ofDays(1).equals(Period.ofDays(1)), true);
876         assertEquals(Period.ofDays(1).equals(Period.ofDays(2)), false);
877 
878         assertEquals(Period.of(1, 2, 3).equals(Period.of(1, 2, 3)), true);
879         assertEquals(Period.of(1, 2, 3).equals(Period.of(0, 2, 3)), false);
880         assertEquals(Period.of(1, 2, 3).equals(Period.of(1, 0, 3)), false);
881         assertEquals(Period.of(1, 2, 3).equals(Period.of(1, 2, 0)), false);
882     }
883 
test_equals_self()884     public void test_equals_self() {
885         Period test = Period.of(1, 2, 3);
886         assertEquals(test.equals(test), true);
887     }
888 
test_equals_null()889     public void test_equals_null() {
890         Period test = Period.of(1, 2, 3);
891         assertEquals(test.equals(null), false);
892     }
893 
test_equals_otherClass()894     public void test_equals_otherClass() {
895         Period test = Period.of(1, 2, 3);
896         assertEquals(test.equals(""), false);
897     }
898 
899     //-----------------------------------------------------------------------
test_hashCode()900     public void test_hashCode() {
901         Period test5 = Period.ofDays(5);
902         Period test6 = Period.ofDays(6);
903         Period test5M = Period.ofMonths(5);
904         Period test5Y = Period.ofYears(5);
905         assertEquals(test5.hashCode() == test5.hashCode(), true);
906         assertEquals(test5.hashCode() == test6.hashCode(), false);
907         assertEquals(test5.hashCode() == test5M.hashCode(), false);
908         assertEquals(test5.hashCode() == test5Y.hashCode(), false);
909     }
910 
911     //-----------------------------------------------------------------------
912     // toString()
913     //-----------------------------------------------------------------------
914     @DataProvider(name="toStringAndParse")
data_toString()915     Object[][] data_toString() {
916         return new Object[][] {
917             {Period.ZERO, "P0D"},
918             {Period.ofDays(0), "P0D"},
919             {Period.ofYears(1), "P1Y"},
920             {Period.ofMonths(1), "P1M"},
921             {Period.ofDays(1), "P1D"},
922             {Period.of(1, 2, 3), "P1Y2M3D"},
923         };
924     }
925 
926     @Test(dataProvider="toStringAndParse")
test_toString(Period input, String expected)927     public void test_toString(Period input, String expected) {
928         assertEquals(input.toString(), expected);
929     }
930 
931     //-----------------------------------------------------------------------
assertPeriod(Period test, int y, int mo, int d)932     private void assertPeriod(Period test, int y, int mo, int d) {
933         assertEquals(test.getYears(), y, "years");
934         assertEquals(test.getMonths(), mo, "months");
935         assertEquals(test.getDays(), d, "days");
936     }
937 
pymd(int y, int m, int d)938     private static Period pymd(int y, int m, int d) {
939         return Period.of(y, m, d);
940     }
941 
date(int y, int m, int d)942     private static LocalDate date(int y, int m, int d) {
943         return LocalDate.of(y, m, d);
944     }
945 
946 }
947