1 /*
2  * Copyright (c) 2012, 2018, 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 test.java.time;
61 
62 import static java.time.temporal.ChronoField.YEAR;
63 import static org.testng.Assert.assertEquals;
64 import static org.testng.Assert.assertSame;
65 import static org.testng.Assert.assertTrue;
66 
67 import java.time.LocalDate;
68 import java.time.Month;
69 import java.time.temporal.ChronoUnit;
70 import java.time.temporal.IsoFields;
71 
72 import org.testng.annotations.BeforeMethod;
73 import org.testng.annotations.DataProvider;
74 import org.testng.annotations.Test;
75 
76 /**
77  * Test LocalDate.
78  */
79 @Test
80 public class TestLocalDate extends AbstractTest {
81 
82     private LocalDate TEST_2007_07_15;
83 
84     @BeforeMethod
setUp()85     public void setUp() {
86         TEST_2007_07_15 = LocalDate.of(2007, 7, 15);
87     }
88 
89     //-----------------------------------------------------------------------
90     @Test
test_immutable()91     public void test_immutable() {
92         assertImmutable(LocalDate.class);
93     }
94 
95     //-----------------------------------------------------------------------
96     // Since plusDays/minusDays actually depends on MJDays, it cannot be used for testing
next(LocalDate date)97     private LocalDate next(LocalDate date) {
98         int newDayOfMonth = date.getDayOfMonth() + 1;
99         if (newDayOfMonth <= date.getMonth().length(isIsoLeap(date.getYear()))) {
100             return date.withDayOfMonth(newDayOfMonth);
101         }
102         date = date.withDayOfMonth(1);
103         if (date.getMonth() == Month.DECEMBER) {
104             date = date.withYear(date.getYear() + 1);
105         }
106         return date.with(date.getMonth().plus(1));
107     }
108 
previous(LocalDate date)109     private LocalDate previous(LocalDate date) {
110         int newDayOfMonth = date.getDayOfMonth() - 1;
111         if (newDayOfMonth > 0) {
112             return date.withDayOfMonth(newDayOfMonth);
113         }
114         date = date.with(date.getMonth().minus(1));
115         if (date.getMonth() == Month.DECEMBER) {
116             date = date.withYear(date.getYear() - 1);
117         }
118         return date.withDayOfMonth(date.getMonth().length(isIsoLeap(date.getYear())));
119     }
120 
121     @Test
test_with_DateTimeField_long_noChange_same()122     public void test_with_DateTimeField_long_noChange_same() {
123         LocalDate t = TEST_2007_07_15.with(YEAR, 2007);
124         assertSame(t, TEST_2007_07_15);
125     }
126 
127     @Test
test_withYear_int_noChange_same()128     public void test_withYear_int_noChange_same() {
129         LocalDate t = TEST_2007_07_15.withYear(2007);
130         assertSame(t, TEST_2007_07_15);
131     }
132 
133     @Test
test_withMonth_int_noChange_same()134     public void test_withMonth_int_noChange_same() {
135         LocalDate t = TEST_2007_07_15.withMonth(7);
136         assertSame(t, TEST_2007_07_15);
137     }
138 
139     @Test
test_withDayOfMonth_noChange_same()140     public void test_withDayOfMonth_noChange_same() {
141         LocalDate t = TEST_2007_07_15.withDayOfMonth(15);
142         assertSame(t, TEST_2007_07_15);
143     }
144 
145     @Test
test_withDayOfYear_noChange_same()146     public void test_withDayOfYear_noChange_same() {
147         LocalDate t = TEST_2007_07_15.withDayOfYear(31 + 28 + 31 + 30 + 31 + 30 + 15);
148         assertSame(t, TEST_2007_07_15);
149     }
150 
151     @Test
test_plus_Period_zero()152     public void test_plus_Period_zero() {
153         LocalDate t = TEST_2007_07_15.plus(MockSimplePeriod.ZERO_DAYS);
154         assertSame(t, TEST_2007_07_15);
155     }
156 
157     @Test
test_plus_longPeriodUnit_zero()158     public void test_plus_longPeriodUnit_zero() {
159         LocalDate t = TEST_2007_07_15.plus(0, ChronoUnit.DAYS);
160         assertSame(t, TEST_2007_07_15);
161     }
162 
163     @Test
test_plusYears_long_noChange_same()164     public void test_plusYears_long_noChange_same() {
165         LocalDate t = TEST_2007_07_15.plusYears(0);
166         assertSame(t, TEST_2007_07_15);
167     }
168 
169     @Test
test_plusMonths_long_noChange_same()170     public void test_plusMonths_long_noChange_same() {
171         LocalDate t = TEST_2007_07_15.plusMonths(0);
172         assertSame(t, TEST_2007_07_15);
173     }
174 
175     //-----------------------------------------------------------------------
176     // plusWeeks()
177     //-----------------------------------------------------------------------
178     @DataProvider(name="samplePlusWeeksSymmetry")
provider_samplePlusWeeksSymmetry()179     Object[][] provider_samplePlusWeeksSymmetry() {
180         return new Object[][] {
181             {LocalDate.of(-1, 1, 1)},
182             {LocalDate.of(-1, 2, 28)},
183             {LocalDate.of(-1, 3, 1)},
184             {LocalDate.of(-1, 12, 31)},
185             {LocalDate.of(0, 1, 1)},
186             {LocalDate.of(0, 2, 28)},
187             {LocalDate.of(0, 2, 29)},
188             {LocalDate.of(0, 3, 1)},
189             {LocalDate.of(0, 12, 31)},
190             {LocalDate.of(2007, 1, 1)},
191             {LocalDate.of(2007, 2, 28)},
192             {LocalDate.of(2007, 3, 1)},
193             {LocalDate.of(2007, 12, 31)},
194             {LocalDate.of(2008, 1, 1)},
195             {LocalDate.of(2008, 2, 28)},
196             {LocalDate.of(2008, 2, 29)},
197             {LocalDate.of(2008, 3, 1)},
198             {LocalDate.of(2008, 12, 31)},
199             {LocalDate.of(2099, 1, 1)},
200             {LocalDate.of(2099, 2, 28)},
201             {LocalDate.of(2099, 3, 1)},
202             {LocalDate.of(2099, 12, 31)},
203             {LocalDate.of(2100, 1, 1)},
204             {LocalDate.of(2100, 2, 28)},
205             {LocalDate.of(2100, 3, 1)},
206             {LocalDate.of(2100, 12, 31)},
207         };
208     }
209 
210     @Test(dataProvider="samplePlusWeeksSymmetry")
test_plusWeeks_symmetry(LocalDate reference)211     public void test_plusWeeks_symmetry(LocalDate reference) {
212         for (int weeks = 0; weeks < 365 * 8; weeks++) {
213             LocalDate t = reference.plusWeeks(weeks).plusWeeks(-weeks);
214             assertEquals(t, reference);
215 
216             t = reference.plusWeeks(-weeks).plusWeeks(weeks);
217             assertEquals(t, reference);
218         }
219     }
220 
221     @Test
test_plusWeeks_noChange_same()222     public void test_plusWeeks_noChange_same() {
223         LocalDate t = TEST_2007_07_15.plusWeeks(0);
224         assertSame(t, TEST_2007_07_15);
225     }
226 
227     //-----------------------------------------------------------------------
228     // plusDays()
229     //-----------------------------------------------------------------------
230     @DataProvider(name="samplePlusDaysSymmetry")
provider_samplePlusDaysSymmetry()231     Object[][] provider_samplePlusDaysSymmetry() {
232         return new Object[][] {
233             {LocalDate.of(-1, 1, 1)},
234             {LocalDate.of(-1, 2, 28)},
235             {LocalDate.of(-1, 3, 1)},
236             {LocalDate.of(-1, 12, 31)},
237             {LocalDate.of(0, 1, 1)},
238             {LocalDate.of(0, 2, 28)},
239             {LocalDate.of(0, 2, 29)},
240             {LocalDate.of(0, 3, 1)},
241             {LocalDate.of(0, 12, 31)},
242             {LocalDate.of(2007, 1, 1)},
243             {LocalDate.of(2007, 2, 28)},
244             {LocalDate.of(2007, 3, 1)},
245             {LocalDate.of(2007, 12, 31)},
246             {LocalDate.of(2008, 1, 1)},
247             {LocalDate.of(2008, 2, 28)},
248             {LocalDate.of(2008, 2, 29)},
249             {LocalDate.of(2008, 3, 1)},
250             {LocalDate.of(2008, 12, 31)},
251             {LocalDate.of(2099, 1, 1)},
252             {LocalDate.of(2099, 2, 28)},
253             {LocalDate.of(2099, 3, 1)},
254             {LocalDate.of(2099, 12, 31)},
255             {LocalDate.of(2100, 1, 1)},
256             {LocalDate.of(2100, 2, 28)},
257             {LocalDate.of(2100, 3, 1)},
258             {LocalDate.of(2100, 12, 31)},
259         };
260     }
261 
262     @Test(dataProvider="samplePlusDaysSymmetry")
test_plusDays_symmetry(LocalDate reference)263     public void test_plusDays_symmetry(LocalDate reference) {
264         for (int days = 0; days < 365 * 8; days++) {
265             LocalDate t = reference.plusDays(days).plusDays(-days);
266             assertEquals(t, reference);
267 
268             t = reference.plusDays(-days).plusDays(days);
269             assertEquals(t, reference);
270         }
271     }
272 
273     @Test
test_plusDays_noChange_same()274     public void test_plusDays_noChange_same() {
275         LocalDate t = TEST_2007_07_15.plusDays(0);
276         assertSame(t, TEST_2007_07_15);
277     }
278 
279     @Test
test_minus_Period_zero()280     public void test_minus_Period_zero() {
281         LocalDate t = TEST_2007_07_15.minus(MockSimplePeriod.ZERO_DAYS);
282         assertSame(t, TEST_2007_07_15);
283     }
284 
285     @Test
test_minus_longPeriodUnit_zero()286     public void test_minus_longPeriodUnit_zero() {
287         LocalDate t = TEST_2007_07_15.minus(0, ChronoUnit.DAYS);
288         assertSame(t, TEST_2007_07_15);
289     }
290 
291     @Test
test_minusYears_long_noChange_same()292     public void test_minusYears_long_noChange_same() {
293         LocalDate t = TEST_2007_07_15.minusYears(0);
294         assertSame(t, TEST_2007_07_15);
295     }
296 
297     @Test
test_minusMonths_long_noChange_same()298     public void test_minusMonths_long_noChange_same() {
299         LocalDate t = TEST_2007_07_15.minusMonths(0);
300         assertSame(t, TEST_2007_07_15);
301     }
302 
303     //-----------------------------------------------------------------------
304     // minusWeeks()
305     //-----------------------------------------------------------------------
306     @DataProvider(name="sampleMinusWeeksSymmetry")
provider_sampleMinusWeeksSymmetry()307     Object[][] provider_sampleMinusWeeksSymmetry() {
308         return new Object[][] {
309             {LocalDate.of(-1, 1, 1)},
310             {LocalDate.of(-1, 2, 28)},
311             {LocalDate.of(-1, 3, 1)},
312             {LocalDate.of(-1, 12, 31)},
313             {LocalDate.of(0, 1, 1)},
314             {LocalDate.of(0, 2, 28)},
315             {LocalDate.of(0, 2, 29)},
316             {LocalDate.of(0, 3, 1)},
317             {LocalDate.of(0, 12, 31)},
318             {LocalDate.of(2007, 1, 1)},
319             {LocalDate.of(2007, 2, 28)},
320             {LocalDate.of(2007, 3, 1)},
321             {LocalDate.of(2007, 12, 31)},
322             {LocalDate.of(2008, 1, 1)},
323             {LocalDate.of(2008, 2, 28)},
324             {LocalDate.of(2008, 2, 29)},
325             {LocalDate.of(2008, 3, 1)},
326             {LocalDate.of(2008, 12, 31)},
327             {LocalDate.of(2099, 1, 1)},
328             {LocalDate.of(2099, 2, 28)},
329             {LocalDate.of(2099, 3, 1)},
330             {LocalDate.of(2099, 12, 31)},
331             {LocalDate.of(2100, 1, 1)},
332             {LocalDate.of(2100, 2, 28)},
333             {LocalDate.of(2100, 3, 1)},
334             {LocalDate.of(2100, 12, 31)},
335         };
336     }
337 
338     @Test(dataProvider="sampleMinusWeeksSymmetry")
test_minusWeeks_symmetry(LocalDate reference)339     public void test_minusWeeks_symmetry(LocalDate reference) {
340         for (int weeks = 0; weeks < 365 * 8; weeks++) {
341             LocalDate t = reference.minusWeeks(weeks).minusWeeks(-weeks);
342             assertEquals(t, reference);
343 
344             t = reference.minusWeeks(-weeks).minusWeeks(weeks);
345             assertEquals(t, reference);
346         }
347     }
348 
349     @Test
test_minusWeeks_noChange_same()350     public void test_minusWeeks_noChange_same() {
351         LocalDate t = TEST_2007_07_15.minusWeeks(0);
352         assertSame(t, TEST_2007_07_15);
353     }
354 
355     //-----------------------------------------------------------------------
356     // minusDays()
357     //-----------------------------------------------------------------------
358     @DataProvider(name="sampleMinusDaysSymmetry")
provider_sampleMinusDaysSymmetry()359     Object[][] provider_sampleMinusDaysSymmetry() {
360         return new Object[][] {
361             {LocalDate.of(-1, 1, 1)},
362             {LocalDate.of(-1, 2, 28)},
363             {LocalDate.of(-1, 3, 1)},
364             {LocalDate.of(-1, 12, 31)},
365             {LocalDate.of(0, 1, 1)},
366             {LocalDate.of(0, 2, 28)},
367             {LocalDate.of(0, 2, 29)},
368             {LocalDate.of(0, 3, 1)},
369             {LocalDate.of(0, 12, 31)},
370             {LocalDate.of(2007, 1, 1)},
371             {LocalDate.of(2007, 2, 28)},
372             {LocalDate.of(2007, 3, 1)},
373             {LocalDate.of(2007, 12, 31)},
374             {LocalDate.of(2008, 1, 1)},
375             {LocalDate.of(2008, 2, 28)},
376             {LocalDate.of(2008, 2, 29)},
377             {LocalDate.of(2008, 3, 1)},
378             {LocalDate.of(2008, 12, 31)},
379             {LocalDate.of(2099, 1, 1)},
380             {LocalDate.of(2099, 2, 28)},
381             {LocalDate.of(2099, 3, 1)},
382             {LocalDate.of(2099, 12, 31)},
383             {LocalDate.of(2100, 1, 1)},
384             {LocalDate.of(2100, 2, 28)},
385             {LocalDate.of(2100, 3, 1)},
386             {LocalDate.of(2100, 12, 31)},
387         };
388     }
389 
390     @Test(dataProvider="sampleMinusDaysSymmetry")
test_minusDays_symmetry(LocalDate reference)391     public void test_minusDays_symmetry(LocalDate reference) {
392         for (int days = 0; days < 365 * 8; days++) {
393             LocalDate t = reference.minusDays(days).minusDays(-days);
394             assertEquals(t, reference);
395 
396             t = reference.minusDays(-days).minusDays(days);
397             assertEquals(t, reference);
398         }
399     }
400 
401     @Test
test_minusDays_noChange_same()402     public void test_minusDays_noChange_same() {
403         LocalDate t = TEST_2007_07_15.minusDays(0);
404         assertSame(t, TEST_2007_07_15);
405     }
406 
407     @Test
test_toEpochDay_fromMJDays_symmetry()408     public void test_toEpochDay_fromMJDays_symmetry() {
409         long date_0000_01_01 = -678941 - 40587;
410 
411         LocalDate test = LocalDate.of(0, 1, 1);
412         for (long i = date_0000_01_01; i < 700000; i++) {
413             assertEquals(LocalDate.ofEpochDay(test.toEpochDay()), test);
414             test = next(test);
415         }
416         test = LocalDate.of(0, 1, 1);
417         for (long i = date_0000_01_01; i > -2000000; i--) {
418             assertEquals(LocalDate.ofEpochDay(test.toEpochDay()), test);
419             test = previous(test);
420         }
421     }
422 
doTest_comparisons_LocalDate(LocalDate... localDates)423     void doTest_comparisons_LocalDate(LocalDate... localDates) {
424         for (int i = 0; i < localDates.length; i++) {
425             LocalDate a = localDates[i];
426             for (int j = 0; j < localDates.length; j++) {
427                 LocalDate b = localDates[j];
428                 if (i < j) {
429                     assertTrue(a.compareTo(b) < 0, a + " <=> " + b);
430                     assertEquals(a.isBefore(b), true, a + " <=> " + b);
431                     assertEquals(a.isAfter(b), false, a + " <=> " + b);
432                     assertEquals(a.equals(b), false, a + " <=> " + b);
433                 } else if (i > j) {
434                     assertTrue(a.compareTo(b) > 0, a + " <=> " + b);
435                     assertEquals(a.isBefore(b), false, a + " <=> " + b);
436                     assertEquals(a.isAfter(b), true, a + " <=> " + b);
437                     assertEquals(a.equals(b), false, a + " <=> " + b);
438                 } else {
439                     assertEquals(a.compareTo(b), 0, a + " <=> " + b);
440                     assertEquals(a.isBefore(b), false, a + " <=> " + b);
441                     assertEquals(a.isAfter(b), false, a + " <=> " + b);
442                     assertEquals(a.equals(b), true, a + " <=> " + b);
443                 }
444             }
445         }
446     }
447 
448     @DataProvider(name="quarterYearsToAdd")
provider_quarterYearsToAdd()449     Object[][] provider_quarterYearsToAdd() {
450         return new Object[][] {
451             {Long.valueOf(-1000000000)},
452             {Long.valueOf(-256)},
453             {Long.valueOf(-255)},
454             {Long.valueOf(-1)},
455             {Long.valueOf(0)},
456             {Long.valueOf(1)},
457             {Long.valueOf(255)},
458             {Long.valueOf(256)},
459             {Long.valueOf(1000000000)},
460         };
461     }
462 
463     @Test(dataProvider="quarterYearsToAdd")
test_plus_QuarterYears(long quarterYears)464     public void test_plus_QuarterYears(long quarterYears) {
465         LocalDate t0 = TEST_2007_07_15
466                 .plus(quarterYears, IsoFields.QUARTER_YEARS);
467         LocalDate t1 = TEST_2007_07_15
468                 .plus(quarterYears, ChronoUnit.MONTHS)
469                 .plus(quarterYears, ChronoUnit.MONTHS)
470                 .plus(quarterYears, ChronoUnit.MONTHS);
471         assertEquals(t0, t1);
472     }
473 
474     @Test(dataProvider="quarterYearsToAdd")
test_minus_QuarterYears(long quarterYears)475     public void test_minus_QuarterYears(long quarterYears) {
476         LocalDate t0 = TEST_2007_07_15
477                 .minus(quarterYears, IsoFields.QUARTER_YEARS);
478         LocalDate t1 = TEST_2007_07_15
479                 .minus(quarterYears, ChronoUnit.MONTHS)
480                 .minus(quarterYears, ChronoUnit.MONTHS)
481                 .minus(quarterYears, ChronoUnit.MONTHS);
482         assertEquals(t0, t1);
483     }
484 }
485