• 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.chrono;
33 
34 import static org.testng.Assert.assertEquals;
35 import static org.testng.Assert.assertTrue;
36 
37 import java.io.ByteArrayInputStream;
38 import java.io.ByteArrayOutputStream;
39 import java.io.ObjectInputStream;
40 import java.io.ObjectOutputStream;
41 import java.util.ArrayList;
42 import java.util.List;
43 import java.util.Locale;
44 import java.util.Map;
45 
46 import org.testng.Assert;
47 import org.testng.annotations.DataProvider;
48 import org.testng.annotations.Test;
49 import org.threeten.bp.Duration;
50 import org.threeten.bp.LocalDate;
51 import org.threeten.bp.format.ResolverStyle;
52 import org.threeten.bp.temporal.ChronoUnit;
53 import org.threeten.bp.temporal.Temporal;
54 import org.threeten.bp.temporal.TemporalAccessor;
55 import org.threeten.bp.temporal.TemporalAdjuster;
56 import org.threeten.bp.temporal.TemporalAmount;
57 import org.threeten.bp.temporal.TemporalField;
58 import org.threeten.bp.temporal.TemporalUnit;
59 import org.threeten.bp.temporal.ValueRange;
60 
61 /**
62  * Test assertions that must be true for all built-in chronologies.
63  */
64 @Test
65 public class TestChronoLocalDate {
66     //-----------------------------------------------------------------------
67     // regular data factory for names and descriptions of available calendars
68     //-----------------------------------------------------------------------
69     @DataProvider(name = "calendars")
data_of_calendars()70     Chronology[][] data_of_calendars() {
71         return new Chronology[][]{
72                     {HijrahChronology.INSTANCE},
73                     {IsoChronology.INSTANCE},
74                     {JapaneseChronology.INSTANCE},
75                     {MinguoChronology.INSTANCE},
76                     {ThaiBuddhistChronology.INSTANCE}};
77     }
78 
79     @Test(dataProvider="calendars")
test_badWithAdjusterChrono(Chronology chrono)80     public void test_badWithAdjusterChrono(Chronology chrono) {
81         LocalDate refDate = LocalDate.of(1900, 1, 1);
82         ChronoLocalDate date = chrono.date(refDate);
83         for (Chronology[] clist : data_of_calendars()) {
84             Chronology chrono2 = clist[0];
85             ChronoLocalDate date2 = chrono2.date(refDate);
86             TemporalAdjuster adjuster = new FixedAdjuster(date2);
87             if (chrono != chrono2) {
88                 try {
89                     date.with(adjuster);
90                     Assert.fail("WithAdjuster should have thrown a ClassCastException");
91                 } catch (ClassCastException cce) {
92                     // Expected exception; not an error
93                 }
94             } else {
95                 // Same chronology,
96                 ChronoLocalDate result = date.with(adjuster);
97                 assertEquals(result, date2, "WithAdjuster failed to replace date");
98             }
99         }
100     }
101 
102     @Test(dataProvider="calendars")
test_badPlusAdjusterChrono(Chronology chrono)103     public void test_badPlusAdjusterChrono(Chronology chrono) {
104         LocalDate refDate = LocalDate.of(1900, 1, 1);
105         ChronoLocalDate date = chrono.date(refDate);
106         for (Chronology[] clist : data_of_calendars()) {
107             Chronology chrono2 = clist[0];
108             ChronoLocalDate date2 = chrono2.date(refDate);
109             TemporalAmount adjuster = new FixedAdjuster(date2);
110             if (chrono != chrono2) {
111                 try {
112                     date.plus(adjuster);
113                     Assert.fail("WithAdjuster should have thrown a ClassCastException");
114                 } catch (ClassCastException cce) {
115                     // Expected exception; not an error
116                 }
117             } else {
118                 // Same chronology,
119                 ChronoLocalDate result = date.plus(adjuster);
120                 assertEquals(result, date2, "WithAdjuster failed to replace date");
121             }
122         }
123     }
124 
125     @Test(dataProvider="calendars")
test_badMinusAdjusterChrono(Chronology chrono)126     public void test_badMinusAdjusterChrono(Chronology chrono) {
127         LocalDate refDate = LocalDate.of(1900, 1, 1);
128         ChronoLocalDate date = chrono.date(refDate);
129         for (Chronology[] clist : data_of_calendars()) {
130             Chronology chrono2 = clist[0];
131             ChronoLocalDate date2 = chrono2.date(refDate);
132             TemporalAmount adjuster = new FixedAdjuster(date2);
133             if (chrono != chrono2) {
134                 try {
135                     date.minus(adjuster);
136                     Assert.fail("WithAdjuster should have thrown a ClassCastException");
137                 } catch (ClassCastException cce) {
138                     // Expected exception; not an error
139                 }
140             } else {
141                 // Same chronology,
142                 ChronoLocalDate result = date.minus(adjuster);
143                 assertEquals(result, date2, "WithAdjuster failed to replace date");
144             }
145         }
146     }
147 
148     @Test(dataProvider="calendars")
test_badPlusPeriodUnitChrono(Chronology chrono)149     public void test_badPlusPeriodUnitChrono(Chronology chrono) {
150         LocalDate refDate = LocalDate.of(1900, 1, 1);
151         ChronoLocalDate date = chrono.date(refDate);
152         for (Chronology[] clist : data_of_calendars()) {
153             Chronology chrono2 = clist[0];
154             ChronoLocalDate date2 = chrono2.date(refDate);
155             TemporalUnit adjuster = new FixedPeriodUnit(date2);
156             if (chrono != chrono2) {
157                 try {
158                     date.plus(1, adjuster);
159                     Assert.fail("PeriodUnit.doAdd plus should have thrown a ClassCastException" + date.getClass()
160                             + ", can not be cast to " + date2.getClass());
161                 } catch (ClassCastException cce) {
162                     // Expected exception; not an error
163                 }
164             } else {
165                 // Same chronology,
166                 ChronoLocalDate result = date.plus(1, adjuster);
167                 assertEquals(result, date2, "WithAdjuster failed to replace date");
168             }
169         }
170     }
171 
172     @Test(dataProvider="calendars")
test_badMinusPeriodUnitChrono(Chronology chrono)173     public void test_badMinusPeriodUnitChrono(Chronology chrono) {
174         LocalDate refDate = LocalDate.of(1900, 1, 1);
175         ChronoLocalDate date = chrono.date(refDate);
176         for (Chronology[] clist : data_of_calendars()) {
177             Chronology chrono2 = clist[0];
178             ChronoLocalDate date2 = chrono2.date(refDate);
179             TemporalUnit adjuster = new FixedPeriodUnit(date2);
180             if (chrono != chrono2) {
181                 try {
182                     date.minus(1, adjuster);
183                     Assert.fail("PeriodUnit.doAdd minus should have thrown a ClassCastException" + date.getClass()
184                             + ", can not be cast to " + date2.getClass());
185                 } catch (ClassCastException cce) {
186                     // Expected exception; not an error
187                 }
188             } else {
189                 // Same chronology,
190                 ChronoLocalDate result = date.minus(1, adjuster);
191                 assertEquals(result, date2, "WithAdjuster failed to replace date");
192             }
193         }
194     }
195 
196     @Test(dataProvider="calendars")
test_badDateTimeFieldChrono(Chronology chrono)197     public void test_badDateTimeFieldChrono(Chronology chrono) {
198         LocalDate refDate = LocalDate.of(1900, 1, 1);
199         ChronoLocalDate date = chrono.date(refDate);
200         for (Chronology[] clist : data_of_calendars()) {
201             Chronology chrono2 = clist[0];
202             ChronoLocalDate date2 = chrono2.date(refDate);
203             TemporalField adjuster = new FixedDateTimeField(date2);
204             if (chrono != chrono2) {
205                 try {
206                     date.with(adjuster, 1);
207                     Assert.fail("DateTimeField doSet should have thrown a ClassCastException" + date.getClass()
208                             + ", can not be cast to " + date2.getClass());
209                 } catch (ClassCastException cce) {
210                     // Expected exception; not an error
211                 }
212             } else {
213                 // Same chronology,
214                 ChronoLocalDate result = date.with(adjuster, 1);
215                 assertEquals(result, date2, "DateTimeField doSet failed to replace date");
216             }
217         }
218     }
219 
220     //-----------------------------------------------------------------------
221     // isBefore, isAfter, isEqual, DATE_COMPARATOR
222     //-----------------------------------------------------------------------
223     @Test(dataProvider="calendars")
test_date_comparisons(Chronology chrono)224     public void test_date_comparisons(Chronology chrono) {
225         List<ChronoLocalDate> dates = new ArrayList<ChronoLocalDate>();
226 
227         ChronoLocalDate date = chrono.date(LocalDate.of(1900, 1, 1));
228 
229         // Insert dates in order, no duplicates
230         if (chrono != JapaneseChronology.INSTANCE) {
231             dates.add(date.minus(1000, ChronoUnit.YEARS));
232             dates.add(date.minus(100, ChronoUnit.YEARS));
233         }
234         dates.add(date.minus(10, ChronoUnit.YEARS));
235         dates.add(date.minus(1, ChronoUnit.YEARS));
236         dates.add(date.minus(1, ChronoUnit.MONTHS));
237         dates.add(date.minus(1, ChronoUnit.WEEKS));
238         dates.add(date.minus(1, ChronoUnit.DAYS));
239         dates.add(date);
240         dates.add(date.plus(1, ChronoUnit.DAYS));
241         dates.add(date.plus(1, ChronoUnit.WEEKS));
242         dates.add(date.plus(1, ChronoUnit.MONTHS));
243         dates.add(date.plus(1, ChronoUnit.YEARS));
244         dates.add(date.plus(10, ChronoUnit.YEARS));
245         dates.add(date.plus(100, ChronoUnit.YEARS));
246         dates.add(date.plus(1000, ChronoUnit.YEARS));
247 
248         // Check these dates against the corresponding dates for every calendar
249         for (Chronology[] clist : data_of_calendars()) {
250             List<ChronoLocalDate> otherDates = new ArrayList<ChronoLocalDate>();
251             Chronology chrono2 = clist[0];
252             if (chrono2 == JapaneseChronology.INSTANCE) {
253                 continue;
254             }
255             for (ChronoLocalDate d : dates) {
256                 otherDates.add(chrono2.date(d));
257             }
258 
259             // Now compare  the sequence of original dates with the sequence of converted dates
260             for (int i = 0; i < dates.size(); i++) {
261                 ChronoLocalDate a = dates.get(i);
262                 for (int j = 0; j < otherDates.size(); j++) {
263                     ChronoLocalDate b = otherDates.get(j);
264                     int cmp = ChronoLocalDate.timeLineOrder().compare(a, b);
265                     if (i < j) {
266                         assertTrue(cmp < 0, a + " compare " + b);
267                         assertEquals(a.isBefore(b), true, a + " isBefore " + b);
268                         assertEquals(a.isAfter(b), false, a + " isAfter " + b);
269                         assertEquals(a.isEqual(b), false, a + " isEqual " + b);
270                     } else if (i > j) {
271                         assertTrue(cmp > 0, a + " compare " + b);
272                         assertEquals(a.isBefore(b), false, a + " isBefore " + b);
273                         assertEquals(a.isAfter(b), true, a + " isAfter " + b);
274                         assertEquals(a.isEqual(b), false, a + " isEqual " + b);
275                     } else {
276                         assertTrue(cmp == 0, a + " compare " + b);
277                         assertEquals(a.isBefore(b), false, a + " isBefore " + b);
278                         assertEquals(a.isAfter(b), false, a + " isAfter " + b);
279                         assertEquals(a.isEqual(b), true, a + " isEqual " + b);
280                     }
281                 }
282             }
283         }
284     }
285 
286     //-----------------------------------------------------------------------
287     // Test Serialization of Calendars
288     //-----------------------------------------------------------------------
289     @Test( dataProvider="calendars")
test_ChronoSerialization(Chronology chrono)290     public void test_ChronoSerialization(Chronology chrono) throws Exception {
291         LocalDate ref = LocalDate.of(1900, 1, 5);
292         ChronoLocalDate orginal = chrono.date(ref);
293         ByteArrayOutputStream baos = new ByteArrayOutputStream();
294         ObjectOutputStream out = new ObjectOutputStream(baos);
295         out.writeObject(orginal);
296         out.close();
297         ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
298         ObjectInputStream in = new ObjectInputStream(bais);
299         ChronoLocalDate ser = (ChronoLocalDate) in.readObject();
300         assertEquals(ser, orginal, "deserialized date is wrong");
301     }
302 
303     /**
304      * FixedAdjusted returns a fixed DateTime in all adjustments.
305      * Construct an adjuster with the DateTime that should be returned.
306      */
307     static class FixedAdjuster implements TemporalAdjuster, TemporalAmount {
308         private Temporal datetime;
309 
FixedAdjuster(Temporal datetime)310         FixedAdjuster(Temporal datetime) {
311             this.datetime = datetime;
312         }
313 
314         @Override
adjustInto(Temporal ignore)315         public Temporal adjustInto(Temporal ignore) {
316             return datetime;
317         }
318 
319         @Override
addTo(Temporal ignore)320         public Temporal addTo(Temporal ignore) {
321             return datetime;
322         }
323 
324         @Override
subtractFrom(Temporal ignore)325         public Temporal subtractFrom(Temporal ignore) {
326             return datetime;
327         }
328 
329         @Override
getUnits()330         public List<TemporalUnit> getUnits() {
331             throw new UnsupportedOperationException("Not supported yet.");
332         }
333 
334         @Override
get(TemporalUnit unit)335         public long get(TemporalUnit unit) {
336             throw new UnsupportedOperationException("Not supported yet.");
337         }
338     }
339 
340     /**
341      * FixedPeriodUnit returns a fixed DateTime in all adjustments.
342      * Construct an FixedPeriodUnit with the DateTime that should be returned.
343      */
344     static class FixedPeriodUnit implements TemporalUnit {
345         private Temporal dateTime;
346 
FixedPeriodUnit(Temporal dateTime)347         FixedPeriodUnit(Temporal dateTime) {
348             this.dateTime = dateTime;
349         }
350 
351         @Override
toString()352         public String toString() {
353             return "FixedPeriodUnit";
354         }
355 
356         @Override
getDuration()357         public Duration getDuration() {
358             throw new UnsupportedOperationException("Not supported yet.");
359         }
360 
361         @Override
isDurationEstimated()362         public boolean isDurationEstimated() {
363             throw new UnsupportedOperationException("Not supported yet.");
364         }
365 
366         @Override
isDateBased()367         public boolean isDateBased() {
368             throw new UnsupportedOperationException("Not supported yet.");
369         }
370 
371         @Override
isTimeBased()372         public boolean isTimeBased() {
373             throw new UnsupportedOperationException("Not supported yet.");
374         }
375 
376         @Override
isSupportedBy(Temporal dateTime)377         public boolean isSupportedBy(Temporal dateTime) {
378             throw new UnsupportedOperationException("Not supported yet.");
379         }
380 
381         @SuppressWarnings("unchecked")
382         @Override
addTo(R dateTime, long periodToAdd)383         public <R extends Temporal> R addTo(R dateTime, long periodToAdd) {
384             return (R) this.dateTime;
385         }
386 
387         @Override
between(Temporal temporal1, Temporal temporal2)388         public long between(Temporal temporal1, Temporal temporal2) {
389             throw new UnsupportedOperationException("Not supported yet.");
390         }
391     }
392 
393     /**
394      * FixedDateTimeField returns a fixed DateTime in all adjustments.
395      * Construct an FixedDateTimeField with the DateTime that should be returned from doSet.
396      */
397     static class FixedDateTimeField implements TemporalField {
398         private Temporal dateTime;
FixedDateTimeField(Temporal dateTime)399         FixedDateTimeField(Temporal dateTime) {
400             this.dateTime = dateTime;
401         }
402 
403         @Override
toString()404         public String toString() {
405             return "FixedDateTimeField";
406         }
407 
408         @Override
getBaseUnit()409         public TemporalUnit getBaseUnit() {
410             throw new UnsupportedOperationException("Not supported yet.");
411         }
412 
413         @Override
getRangeUnit()414         public TemporalUnit getRangeUnit() {
415             throw new UnsupportedOperationException("Not supported yet.");
416         }
417 
418         @Override
range()419         public ValueRange range() {
420             throw new UnsupportedOperationException("Not supported yet.");
421         }
422 
423         @Override
isDateBased()424         public boolean isDateBased() {
425             throw new UnsupportedOperationException("Not supported yet.");
426         }
427 
428         @Override
isTimeBased()429         public boolean isTimeBased() {
430             throw new UnsupportedOperationException("Not supported yet.");
431         }
432 
433         @Override
isSupportedBy(TemporalAccessor dateTime)434         public boolean isSupportedBy(TemporalAccessor dateTime) {
435             throw new UnsupportedOperationException("Not supported yet.");
436         }
437 
438         @Override
rangeRefinedBy(TemporalAccessor dateTime)439         public ValueRange rangeRefinedBy(TemporalAccessor dateTime) {
440             throw new UnsupportedOperationException("Not supported yet.");
441         }
442 
443         @Override
getFrom(TemporalAccessor dateTime)444         public long getFrom(TemporalAccessor dateTime) {
445             throw new UnsupportedOperationException("Not supported yet.");
446         }
447 
448         @SuppressWarnings("unchecked")
449         @Override
adjustInto(R dateTime, long newValue)450         public <R extends Temporal> R adjustInto(R dateTime, long newValue) {
451             return (R) this.dateTime;
452         }
453 
454         @Override
getDisplayName(Locale locale)455         public String getDisplayName(Locale locale) {
456             throw new UnsupportedOperationException("Not supported yet.");
457         }
458 
459         @Override
resolve(Map<TemporalField, Long> fieldValues, TemporalAccessor partialTemporal, ResolverStyle resolverStyle)460         public TemporalAccessor resolve(Map<TemporalField, Long> fieldValues,
461                         TemporalAccessor partialTemporal, ResolverStyle resolverStyle) {
462             return null;
463         }
464     }
465 }
466