37 * * Redistributions in binary form must reproduce the above copyright notice, 38 * this list of conditions and the following disclaimer in the documentation 39 * and/or other materials provided with the distribution. 40 * 41 * * Neither the name of JSR-310 nor the names of its contributors 42 * may be used to endorse or promote products derived from this software 43 * without specific prior written permission. 44 * 45 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 46 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 47 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 48 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 49 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 50 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 51 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 52 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 53 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 54 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 55 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 56 */ 57 package tck.java.time.calendar; 58 59 import static org.testng.Assert.assertEquals; 60 import static org.testng.Assert.assertTrue; 61 62 import java.io.ByteArrayInputStream; 63 import java.io.ByteArrayOutputStream; 64 import java.io.ObjectInputStream; 65 import java.io.ObjectOutputStream; 66 import java.util.ArrayList; 67 import java.util.List; 68 69 import java.time.Duration; 70 import java.time.LocalDate; 71 import java.time.LocalDateTime; 72 import java.time.LocalTime; 73 import java.time.calendar.HijrahChrono; 74 import java.time.calendar.JapaneseChrono; 75 import java.time.calendar.MinguoChrono; 76 import java.time.calendar.ThaiBuddhistChrono; 77 import java.time.temporal.Chrono; 78 import java.time.temporal.ChronoLocalDateTime; 79 import java.time.temporal.ChronoUnit; 80 import java.time.temporal.SimplePeriod; 81 import java.time.temporal.Temporal; 82 import java.time.temporal.TemporalAccessor; 83 import java.time.format.DateTimeBuilder; 84 import java.time.temporal.TemporalAdder; 85 import java.time.temporal.TemporalAdjuster; 86 import java.time.temporal.TemporalField; 87 import java.time.temporal.TemporalSubtractor; 88 import java.time.temporal.ValueRange; 89 import java.time.temporal.ISOChrono; 90 import java.time.temporal.TemporalUnit; 91 92 import org.testng.Assert; 93 import org.testng.annotations.DataProvider; 94 import org.testng.annotations.Test; 95 96 /** 97 * Test assertions that must be true for all built-in chronologies. 98 */ 99 @Test 100 public class TestChronoLocalDateTime { 101 //----------------------------------------------------------------------- 102 // regular data factory for names and descriptions of available calendars 103 //----------------------------------------------------------------------- 104 @DataProvider(name = "calendars") 105 Chrono[][] data_of_calendars() { 106 return new Chrono[][]{ 107 {HijrahChrono.INSTANCE}, 108 {ISOChrono.INSTANCE}, 109 {JapaneseChrono.INSTANCE}, 110 {MinguoChrono.INSTANCE}, 111 {ThaiBuddhistChrono.INSTANCE}}; 112 } 113 114 @Test(groups={"tck"}, dataProvider="calendars") 115 public void test_badWithAdjusterChrono(Chrono chrono) { 116 LocalDate refDate = LocalDate.of(1900, 1, 1); 117 ChronoLocalDateTime cdt = chrono.date(refDate).atTime(LocalTime.NOON); 118 for (Chrono[] clist : data_of_calendars()) { 119 Chrono chrono2 = clist[0]; 120 ChronoLocalDateTime<?> cdt2 = chrono2.date(refDate).atTime(LocalTime.NOON); 121 TemporalAdjuster adjuster = new FixedAdjuster(cdt2); 122 if (chrono != chrono2) { 123 try { 124 ChronoLocalDateTime<?> notreached = cdt.with(adjuster); 125 Assert.fail("WithAdjuster should have thrown a ClassCastException, " 126 + "required: " + cdt + ", supplied: " + cdt2); 127 } catch (ClassCastException cce) { 128 // Expected exception; not an error 129 } 130 } else { 131 // Same chronology, 132 ChronoLocalDateTime<?> result = cdt.with(adjuster); 133 assertEquals(result, cdt2, "WithAdjuster failed to replace date"); 134 } 135 } 136 } 137 138 @Test(groups={"tck"}, dataProvider="calendars") 139 public void test_badPlusAdjusterChrono(Chrono chrono) { 140 LocalDate refDate = LocalDate.of(1900, 1, 1); 141 ChronoLocalDateTime cdt = chrono.date(refDate).atTime(LocalTime.NOON); 142 for (Chrono[] clist : data_of_calendars()) { 143 Chrono chrono2 = clist[0]; 144 ChronoLocalDateTime<?> cdt2 = chrono2.date(refDate).atTime(LocalTime.NOON); 145 TemporalAdder adjuster = new FixedAdjuster(cdt2); 146 if (chrono != chrono2) { 147 try { 148 ChronoLocalDateTime<?> notreached = cdt.plus(adjuster); 149 Assert.fail("WithAdjuster should have thrown a ClassCastException, " 150 + "required: " + cdt + ", supplied: " + cdt2); 151 } catch (ClassCastException cce) { 152 // Expected exception; not an error 153 } 154 } else { 155 // Same chronology, 156 ChronoLocalDateTime<?> result = cdt.plus(adjuster); 157 assertEquals(result, cdt2, "WithAdjuster failed to replace date time"); 158 } 159 } 160 } 161 162 @Test(groups={"tck"}, dataProvider="calendars") 163 public void test_badMinusAdjusterChrono(Chrono chrono) { 164 LocalDate refDate = LocalDate.of(1900, 1, 1); 165 ChronoLocalDateTime cdt = chrono.date(refDate).atTime(LocalTime.NOON); 166 for (Chrono[] clist : data_of_calendars()) { 167 Chrono chrono2 = clist[0]; 168 ChronoLocalDateTime<?> cdt2 = chrono2.date(refDate).atTime(LocalTime.NOON); 169 TemporalSubtractor adjuster = new FixedAdjuster(cdt2); 170 if (chrono != chrono2) { 171 try { 172 ChronoLocalDateTime<?> notreached = cdt.minus(adjuster); 173 Assert.fail("WithAdjuster should have thrown a ClassCastException, " 174 + "required: " + cdt + ", supplied: " + cdt2); 175 } catch (ClassCastException cce) { 176 // Expected exception; not an error 177 } 178 } else { 179 // Same chronology, 180 ChronoLocalDateTime<?> result = cdt.minus(adjuster); 181 assertEquals(result, cdt2, "WithAdjuster failed to replace date"); 182 } 183 } 184 } 185 186 @Test(groups={"tck"}, dataProvider="calendars") 187 public void test_badPlusTemporalUnitChrono(Chrono chrono) { 188 LocalDate refDate = LocalDate.of(1900, 1, 1); 189 ChronoLocalDateTime cdt = chrono.date(refDate).atTime(LocalTime.NOON); 190 for (Chrono[] clist : data_of_calendars()) { 191 Chrono chrono2 = clist[0]; 192 ChronoLocalDateTime<?> cdt2 = chrono2.date(refDate).atTime(LocalTime.NOON); 193 TemporalUnit adjuster = new FixedTemporalUnit(cdt2); 194 if (chrono != chrono2) { 195 try { 196 ChronoLocalDateTime<?> notreached = cdt.plus(1, adjuster); 197 Assert.fail("TemporalUnit.doAdd plus should have thrown a ClassCastException" + cdt 198 + ", can not be cast to " + cdt2); 199 } catch (ClassCastException cce) { 200 // Expected exception; not an error 201 } 202 } else { 203 // Same chronology, 204 ChronoLocalDateTime<?> result = cdt.plus(1, adjuster); 205 assertEquals(result, cdt2, "WithAdjuster failed to replace date"); 206 } 207 } 208 } 209 210 @Test(groups={"tck"}, dataProvider="calendars") 211 public void test_badMinusTemporalUnitChrono(Chrono chrono) { 212 LocalDate refDate = LocalDate.of(1900, 1, 1); 213 ChronoLocalDateTime cdt = chrono.date(refDate).atTime(LocalTime.NOON); 214 for (Chrono[] clist : data_of_calendars()) { 215 Chrono chrono2 = clist[0]; 216 ChronoLocalDateTime<?> cdt2 = chrono2.date(refDate).atTime(LocalTime.NOON); 217 TemporalUnit adjuster = new FixedTemporalUnit(cdt2); 218 if (chrono != chrono2) { 219 try { 220 ChronoLocalDateTime<?> notreached = cdt.minus(1, adjuster); 221 Assert.fail("TemporalUnit.doAdd minus should have thrown a ClassCastException" + cdt.getClass() 222 + ", can not be cast to " + cdt2.getClass()); 223 } catch (ClassCastException cce) { 224 // Expected exception; not an error 225 } 226 } else { 227 // Same chronology, 228 ChronoLocalDateTime<?> result = cdt.minus(1, adjuster); 229 assertEquals(result, cdt2, "WithAdjuster failed to replace date"); 230 } 231 } 232 } 233 234 @Test(groups={"tck"}, dataProvider="calendars") 235 public void test_badTemporalFieldChrono(Chrono chrono) { 236 LocalDate refDate = LocalDate.of(1900, 1, 1); 237 ChronoLocalDateTime cdt = chrono.date(refDate).atTime(LocalTime.NOON); 238 for (Chrono[] clist : data_of_calendars()) { 239 Chrono chrono2 = clist[0]; 240 ChronoLocalDateTime<?> cdt2 = chrono2.date(refDate).atTime(LocalTime.NOON); 241 TemporalField adjuster = new FixedTemporalField(cdt2); 242 if (chrono != chrono2) { 243 try { 244 ChronoLocalDateTime<?> notreached = cdt.with(adjuster, 1); 245 Assert.fail("TemporalField doSet should have thrown a ClassCastException" + cdt.getClass() 246 + ", can not be cast to " + cdt2.getClass()); 247 } catch (ClassCastException cce) { 248 // Expected exception; not an error 249 } 250 } else { 251 // Same chronology, 252 ChronoLocalDateTime<?> result = cdt.with(adjuster, 1); 253 assertEquals(result, cdt2, "TemporalField doSet failed to replace date"); 254 } 255 } 256 } 257 258 //----------------------------------------------------------------------- 259 // isBefore, isAfter, isEqual 260 //----------------------------------------------------------------------- 261 @Test(groups={"tck"}, dataProvider="calendars") 262 public void test_datetime_comparisons(Chrono chrono) { 263 List<ChronoLocalDateTime<?>> dates = new ArrayList<>(); 264 265 ChronoLocalDateTime<?> date = chrono.date(LocalDate.of(1900, 1, 1)).atTime(LocalTime.MIN); 266 267 // Insert dates in order, no duplicates 268 dates.add(date.minus(100, ChronoUnit.YEARS)); 269 dates.add(date.minus(1, ChronoUnit.YEARS)); 270 dates.add(date.minus(1, ChronoUnit.MONTHS)); 271 dates.add(date.minus(1, ChronoUnit.WEEKS)); 272 dates.add(date.minus(1, ChronoUnit.DAYS)); 273 dates.add(date.minus(1, ChronoUnit.HOURS)); 274 dates.add(date.minus(1, ChronoUnit.MINUTES)); 275 dates.add(date.minus(1, ChronoUnit.SECONDS)); 276 dates.add(date.minus(1, ChronoUnit.NANOS)); 277 dates.add(date); 278 dates.add(date.plus(1, ChronoUnit.NANOS)); 279 dates.add(date.plus(1, ChronoUnit.SECONDS)); 280 dates.add(date.plus(1, ChronoUnit.MINUTES)); 281 dates.add(date.plus(1, ChronoUnit.HOURS)); 282 dates.add(date.plus(1, ChronoUnit.DAYS)); 283 dates.add(date.plus(1, ChronoUnit.WEEKS)); 284 dates.add(date.plus(1, ChronoUnit.MONTHS)); 285 dates.add(date.plus(1, ChronoUnit.YEARS)); 286 dates.add(date.plus(100, ChronoUnit.YEARS)); 287 288 // Check these dates against the corresponding dates for every calendar 289 for (Chrono[] clist : data_of_calendars()) { 290 List<ChronoLocalDateTime<?>> otherDates = new ArrayList<>(); 291 Chrono chrono2 = clist[0]; 292 for (ChronoLocalDateTime<?> d : dates) { 293 otherDates.add(chrono2.date(d).atTime(d.getTime())); 294 } 295 296 // Now compare the sequence of original dates with the sequence of converted dates 297 for (int i = 0; i < dates.size(); i++) { 298 ChronoLocalDateTime<?> a = dates.get(i); 299 for (int j = 0; j < otherDates.size(); j++) { 300 ChronoLocalDateTime<?> b = otherDates.get(j); 301 int cmp = ChronoLocalDateTime.DATE_TIME_COMPARATOR.compare(a, b); 302 if (i < j) { 303 assertTrue(cmp < 0, a + " compare " + b); 304 assertEquals(a.isBefore(b), true, a + " isBefore " + b); 305 assertEquals(a.isAfter(b), false, a + " isAfter " + b); 306 assertEquals(a.isEqual(b), false, a + " isEqual " + b); 307 } else if (i > j) { 308 assertTrue(cmp > 0, a + " compare " + b); 309 assertEquals(a.isBefore(b), false, a + " isBefore " + b); 310 assertEquals(a.isAfter(b), true, a + " isAfter " + b); 311 assertEquals(a.isEqual(b), false, a + " isEqual " + b); 312 } else { 313 assertTrue(cmp == 0, a + " compare " + b); 314 assertEquals(a.isBefore(b), false, a + " isBefore " + b); 315 assertEquals(a.isAfter(b), false, a + " isAfter " + b); 316 assertEquals(a.isEqual(b), true, a + " isEqual " + b); 317 } 318 } 319 } 320 } 321 } 322 323 //----------------------------------------------------------------------- 324 // Test Serialization of ISO via chrono API 325 //----------------------------------------------------------------------- 326 @Test( groups={"tck"}, dataProvider="calendars") 327 public <C extends Chrono<C>> void test_ChronoLocalDateTimeSerialization(C chrono) throws Exception { 328 LocalDateTime ref = LocalDate.of(2000, 1, 5).atTime(12, 1, 2, 3); 329 ChronoLocalDateTime<C> orginal = chrono.date(ref).atTime(ref.getTime()); 330 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 331 ObjectOutputStream out = new ObjectOutputStream(baos); 332 out.writeObject(orginal); 333 out.close(); 334 ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); 335 ObjectInputStream in = new ObjectInputStream(bais); 336 ChronoLocalDateTime<C> ser = (ChronoLocalDateTime<C>) in.readObject(); 337 assertEquals(ser, orginal, "deserialized date is wrong"); 338 } 339 340 341 /** 342 * FixedAdjusted returns a fixed Temporal in all adjustments. 343 * Construct an adjuster with the Temporal that should be returned from adjust. 344 */ 345 static class FixedAdjuster implements TemporalAdjuster, TemporalAdder, TemporalSubtractor { 346 private Temporal datetime; 347 348 FixedAdjuster(Temporal datetime) { 349 this.datetime = datetime; 350 } 351 352 @Override 353 public Temporal adjustInto(Temporal ignore) { 354 return datetime; 355 } 356 357 @Override 358 public Temporal addTo(Temporal ignore) { 359 return datetime; 360 } 361 362 @Override 363 public Temporal subtractFrom(Temporal ignore) { 364 return datetime; 365 } 366 367 } 368 369 /** 370 * FixedTemporalUnit returns a fixed Temporal in all adjustments. 371 * Construct an FixedTemporalUnit with the Temporal that should be returned from doAdd. 372 */ 373 static class FixedTemporalUnit implements TemporalUnit { 374 private Temporal temporal; 375 376 FixedTemporalUnit(Temporal temporal) { 377 this.temporal = temporal; 378 } 379 380 @Override 381 public String getName() { 382 return "FixedTemporalUnit"; 383 } 384 385 @Override 386 public Duration getDuration() { 387 throw new UnsupportedOperationException("Not supported yet."); 388 } 389 390 @Override 391 public boolean isDurationEstimated() { 392 throw new UnsupportedOperationException("Not supported yet."); 393 } 394 395 @Override 396 public boolean isSupported(Temporal temporal) { 397 throw new UnsupportedOperationException("Not supported yet."); 398 } 399 400 @SuppressWarnings("unchecked") 401 @Override 402 public <R extends Temporal> R doPlus(R dateTime, long periodToAdd) { 403 return (R) this.temporal; 404 } 405 406 @Override 407 public <R extends Temporal> SimplePeriod between(R dateTime1, R dateTime2) { 408 throw new UnsupportedOperationException("Not supported yet."); 409 } 410 } 411 412 /** 413 * FixedTemporalField returns a fixed Temporal in all adjustments. 414 * Construct an FixedTemporalField with the Temporal that should be returned from doSet. 415 */ 416 static class FixedTemporalField implements TemporalField { 417 private Temporal temporal; 418 FixedTemporalField(Temporal temporal) { 419 this.temporal = temporal; 420 } 421 422 @Override 423 public String getName() { 424 return "FixedTemporalField"; 425 } 426 427 @Override 428 public TemporalUnit getBaseUnit() { 429 throw new UnsupportedOperationException("Not supported yet."); 430 } 431 432 @Override 433 public TemporalUnit getRangeUnit() { 434 throw new UnsupportedOperationException("Not supported yet."); 435 } 436 437 @Override 438 public ValueRange range() { 439 throw new UnsupportedOperationException("Not supported yet."); 440 } 441 442 @Override 443 public boolean doIsSupported(TemporalAccessor temporal) { 444 throw new UnsupportedOperationException("Not supported yet."); 445 } 446 447 @Override 448 public ValueRange doRange(TemporalAccessor temporal) { 449 throw new UnsupportedOperationException("Not supported yet."); 450 } 451 452 @Override 453 public long doGet(TemporalAccessor temporal) { 454 throw new UnsupportedOperationException("Not supported yet."); 455 } 456 457 @SuppressWarnings("unchecked") 458 @Override 459 public <R extends Temporal> R doWith(R temporal, long newValue) { 460 return (R) this.temporal; 461 } 462 463 @Override 464 public boolean resolve(DateTimeBuilder builder, long value) { 465 throw new UnsupportedOperationException("Not supported yet."); 466 } 467 468 } 469 } | 37 * * Redistributions in binary form must reproduce the above copyright notice, 38 * this list of conditions and the following disclaimer in the documentation 39 * and/or other materials provided with the distribution. 40 * 41 * * Neither the name of JSR-310 nor the names of its contributors 42 * may be used to endorse or promote products derived from this software 43 * without specific prior written permission. 44 * 45 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 46 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 47 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 48 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 49 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 50 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 51 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 52 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 53 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 54 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 55 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 56 */ 57 package tck.java.time.chrono; 58 59 import static org.testng.Assert.assertEquals; 60 import static org.testng.Assert.assertTrue; 61 62 import java.io.ByteArrayInputStream; 63 import java.io.ByteArrayOutputStream; 64 import java.io.ObjectInputStream; 65 import java.io.ObjectOutputStream; 66 import java.time.Duration; 67 import java.time.LocalDate; 68 import java.time.LocalDateTime; 69 import java.time.LocalTime; 70 import java.time.chrono.HijrahChronology; 71 import java.time.chrono.JapaneseChronology; 72 import java.time.chrono.MinguoChronology; 73 import java.time.chrono.ThaiBuddhistChronology; 74 import java.time.chrono.ChronoLocalDate; 75 import java.time.chrono.ChronoLocalDateTime; 76 import java.time.chrono.Chronology; 77 import java.time.chrono.IsoChronology; 78 import java.time.temporal.ChronoUnit; 79 import java.time.temporal.Temporal; 80 import java.time.temporal.TemporalAccessor; 81 import java.time.temporal.TemporalAdjuster; 82 import java.time.temporal.TemporalAmount; 83 import java.time.temporal.TemporalField; 84 import java.time.temporal.TemporalUnit; 85 import java.time.temporal.ValueRange; 86 import java.util.ArrayList; 87 import java.util.List; 88 89 import org.testng.Assert; 90 import org.testng.annotations.DataProvider; 91 import org.testng.annotations.Test; 92 93 /** 94 * Test assertions that must be true for all built-in chronologies. 95 */ 96 @Test 97 public class TestChronoLocalDateTime { 98 //----------------------------------------------------------------------- 99 // regular data factory for names and descriptions of available calendars 100 //----------------------------------------------------------------------- 101 @DataProvider(name = "calendars") 102 Chronology[][] data_of_calendars() { 103 return new Chronology[][]{ 104 {HijrahChronology.INSTANCE}, 105 {IsoChronology.INSTANCE}, 106 {JapaneseChronology.INSTANCE}, 107 {MinguoChronology.INSTANCE}, 108 {ThaiBuddhistChronology.INSTANCE}}; 109 } 110 111 @Test(groups={"tck"}, dataProvider="calendars") 112 public void test_badWithAdjusterChrono(Chronology chrono) { 113 LocalDate refDate = LocalDate.of(1900, 1, 1); 114 ChronoLocalDateTime cdt = chrono.date(refDate).atTime(LocalTime.NOON); 115 for (Chronology[] clist : data_of_calendars()) { 116 Chronology chrono2 = clist[0]; 117 ChronoLocalDateTime<?> cdt2 = chrono2.date(refDate).atTime(LocalTime.NOON); 118 TemporalAdjuster adjuster = new FixedAdjuster(cdt2); 119 if (chrono != chrono2) { 120 try { 121 ChronoLocalDateTime<?> notreached = cdt.with(adjuster); 122 Assert.fail("WithAdjuster should have thrown a ClassCastException, " 123 + "required: " + cdt + ", supplied: " + cdt2); 124 } catch (ClassCastException cce) { 125 // Expected exception; not an error 126 } 127 } else { 128 // Same chronology, 129 ChronoLocalDateTime<?> result = cdt.with(adjuster); 130 assertEquals(result, cdt2, "WithAdjuster failed to replace date"); 131 } 132 } 133 } 134 135 @Test(groups={"tck"}, dataProvider="calendars") 136 public void test_badPlusAdjusterChrono(Chronology chrono) { 137 LocalDate refDate = LocalDate.of(1900, 1, 1); 138 ChronoLocalDateTime cdt = chrono.date(refDate).atTime(LocalTime.NOON); 139 for (Chronology[] clist : data_of_calendars()) { 140 Chronology chrono2 = clist[0]; 141 ChronoLocalDateTime<?> cdt2 = chrono2.date(refDate).atTime(LocalTime.NOON); 142 TemporalAmount adjuster = new FixedAdjuster(cdt2); 143 if (chrono != chrono2) { 144 try { 145 ChronoLocalDateTime<?> notreached = cdt.plus(adjuster); 146 Assert.fail("WithAdjuster should have thrown a ClassCastException, " 147 + "required: " + cdt + ", supplied: " + cdt2); 148 } catch (ClassCastException cce) { 149 // Expected exception; not an error 150 } 151 } else { 152 // Same chronology, 153 ChronoLocalDateTime<?> result = cdt.plus(adjuster); 154 assertEquals(result, cdt2, "WithAdjuster failed to replace date time"); 155 } 156 } 157 } 158 159 @Test(groups={"tck"}, dataProvider="calendars") 160 public void test_badMinusAdjusterChrono(Chronology chrono) { 161 LocalDate refDate = LocalDate.of(1900, 1, 1); 162 ChronoLocalDateTime cdt = chrono.date(refDate).atTime(LocalTime.NOON); 163 for (Chronology[] clist : data_of_calendars()) { 164 Chronology chrono2 = clist[0]; 165 ChronoLocalDateTime<?> cdt2 = chrono2.date(refDate).atTime(LocalTime.NOON); 166 TemporalAmount adjuster = new FixedAdjuster(cdt2); 167 if (chrono != chrono2) { 168 try { 169 ChronoLocalDateTime<?> notreached = cdt.minus(adjuster); 170 Assert.fail("WithAdjuster should have thrown a ClassCastException, " 171 + "required: " + cdt + ", supplied: " + cdt2); 172 } catch (ClassCastException cce) { 173 // Expected exception; not an error 174 } 175 } else { 176 // Same chronology, 177 ChronoLocalDateTime<?> result = cdt.minus(adjuster); 178 assertEquals(result, cdt2, "WithAdjuster failed to replace date"); 179 } 180 } 181 } 182 183 @Test(groups={"tck"}, dataProvider="calendars") 184 public void test_badPlusTemporalUnitChrono(Chronology chrono) { 185 LocalDate refDate = LocalDate.of(1900, 1, 1); 186 ChronoLocalDateTime cdt = chrono.date(refDate).atTime(LocalTime.NOON); 187 for (Chronology[] clist : data_of_calendars()) { 188 Chronology chrono2 = clist[0]; 189 ChronoLocalDateTime<?> cdt2 = chrono2.date(refDate).atTime(LocalTime.NOON); 190 TemporalUnit adjuster = new FixedTemporalUnit(cdt2); 191 if (chrono != chrono2) { 192 try { 193 ChronoLocalDateTime<?> notreached = cdt.plus(1, adjuster); 194 Assert.fail("TemporalUnit.doAdd plus should have thrown a ClassCastException" + cdt 195 + ", can not be cast to " + cdt2); 196 } catch (ClassCastException cce) { 197 // Expected exception; not an error 198 } 199 } else { 200 // Same chronology, 201 ChronoLocalDateTime<?> result = cdt.plus(1, adjuster); 202 assertEquals(result, cdt2, "WithAdjuster failed to replace date"); 203 } 204 } 205 } 206 207 @Test(groups={"tck"}, dataProvider="calendars") 208 public void test_badMinusTemporalUnitChrono(Chronology chrono) { 209 LocalDate refDate = LocalDate.of(1900, 1, 1); 210 ChronoLocalDateTime cdt = chrono.date(refDate).atTime(LocalTime.NOON); 211 for (Chronology[] clist : data_of_calendars()) { 212 Chronology chrono2 = clist[0]; 213 ChronoLocalDateTime<?> cdt2 = chrono2.date(refDate).atTime(LocalTime.NOON); 214 TemporalUnit adjuster = new FixedTemporalUnit(cdt2); 215 if (chrono != chrono2) { 216 try { 217 ChronoLocalDateTime<?> notreached = cdt.minus(1, adjuster); 218 Assert.fail("TemporalUnit.doAdd minus should have thrown a ClassCastException" + cdt.getClass() 219 + ", can not be cast to " + cdt2.getClass()); 220 } catch (ClassCastException cce) { 221 // Expected exception; not an error 222 } 223 } else { 224 // Same chronology, 225 ChronoLocalDateTime<?> result = cdt.minus(1, adjuster); 226 assertEquals(result, cdt2, "WithAdjuster failed to replace date"); 227 } 228 } 229 } 230 231 @Test(groups={"tck"}, dataProvider="calendars") 232 public void test_badTemporalFieldChrono(Chronology chrono) { 233 LocalDate refDate = LocalDate.of(1900, 1, 1); 234 ChronoLocalDateTime cdt = chrono.date(refDate).atTime(LocalTime.NOON); 235 for (Chronology[] clist : data_of_calendars()) { 236 Chronology chrono2 = clist[0]; 237 ChronoLocalDateTime<?> cdt2 = chrono2.date(refDate).atTime(LocalTime.NOON); 238 TemporalField adjuster = new FixedTemporalField(cdt2); 239 if (chrono != chrono2) { 240 try { 241 ChronoLocalDateTime<?> notreached = cdt.with(adjuster, 1); 242 Assert.fail("TemporalField doSet should have thrown a ClassCastException" + cdt.getClass() 243 + ", can not be cast to " + cdt2.getClass()); 244 } catch (ClassCastException cce) { 245 // Expected exception; not an error 246 } 247 } else { 248 // Same chronology, 249 ChronoLocalDateTime<?> result = cdt.with(adjuster, 1); 250 assertEquals(result, cdt2, "TemporalField doSet failed to replace date"); 251 } 252 } 253 } 254 255 //----------------------------------------------------------------------- 256 // isBefore, isAfter, isEqual 257 //----------------------------------------------------------------------- 258 @Test(groups={"tck"}, dataProvider="calendars") 259 public void test_datetime_comparisons(Chronology chrono) { 260 List<ChronoLocalDateTime<?>> dates = new ArrayList<>(); 261 262 ChronoLocalDateTime<?> date = chrono.date(LocalDate.of(1900, 1, 1)).atTime(LocalTime.MIN); 263 264 // Insert dates in order, no duplicates 265 dates.add(date.minus(100, ChronoUnit.YEARS)); 266 dates.add(date.minus(1, ChronoUnit.YEARS)); 267 dates.add(date.minus(1, ChronoUnit.MONTHS)); 268 dates.add(date.minus(1, ChronoUnit.WEEKS)); 269 dates.add(date.minus(1, ChronoUnit.DAYS)); 270 dates.add(date.minus(1, ChronoUnit.HOURS)); 271 dates.add(date.minus(1, ChronoUnit.MINUTES)); 272 dates.add(date.minus(1, ChronoUnit.SECONDS)); 273 dates.add(date.minus(1, ChronoUnit.NANOS)); 274 dates.add(date); 275 dates.add(date.plus(1, ChronoUnit.NANOS)); 276 dates.add(date.plus(1, ChronoUnit.SECONDS)); 277 dates.add(date.plus(1, ChronoUnit.MINUTES)); 278 dates.add(date.plus(1, ChronoUnit.HOURS)); 279 dates.add(date.plus(1, ChronoUnit.DAYS)); 280 dates.add(date.plus(1, ChronoUnit.WEEKS)); 281 dates.add(date.plus(1, ChronoUnit.MONTHS)); 282 dates.add(date.plus(1, ChronoUnit.YEARS)); 283 dates.add(date.plus(100, ChronoUnit.YEARS)); 284 285 // Check these dates against the corresponding dates for every calendar 286 for (Chronology[] clist : data_of_calendars()) { 287 List<ChronoLocalDateTime<?>> otherDates = new ArrayList<>(); 288 Chronology chrono2 = clist[0]; 289 for (ChronoLocalDateTime<?> d : dates) { 290 otherDates.add(chrono2.date(d).atTime(d.toLocalTime())); 291 } 292 293 // Now compare the sequence of original dates with the sequence of converted dates 294 for (int i = 0; i < dates.size(); i++) { 295 ChronoLocalDateTime<?> a = dates.get(i); 296 for (int j = 0; j < otherDates.size(); j++) { 297 ChronoLocalDateTime<?> b = otherDates.get(j); 298 int cmp = ChronoLocalDateTime.DATE_TIME_COMPARATOR.compare(a, b); 299 if (i < j) { 300 assertTrue(cmp < 0, a + " compare " + b); 301 assertEquals(a.isBefore(b), true, a + " isBefore " + b); 302 assertEquals(a.isAfter(b), false, a + " isAfter " + b); 303 assertEquals(a.isEqual(b), false, a + " isEqual " + b); 304 } else if (i > j) { 305 assertTrue(cmp > 0, a + " compare " + b); 306 assertEquals(a.isBefore(b), false, a + " isBefore " + b); 307 assertEquals(a.isAfter(b), true, a + " isAfter " + b); 308 assertEquals(a.isEqual(b), false, a + " isEqual " + b); 309 } else { 310 assertTrue(cmp == 0, a + " compare " + b); 311 assertEquals(a.isBefore(b), false, a + " isBefore " + b); 312 assertEquals(a.isAfter(b), false, a + " isAfter " + b); 313 assertEquals(a.isEqual(b), true, a + " isEqual " + b); 314 } 315 } 316 } 317 } 318 } 319 320 //----------------------------------------------------------------------- 321 // Test Serialization of ISO via chrono API 322 //----------------------------------------------------------------------- 323 @Test( groups={"tck"}, dataProvider="calendars") 324 public void test_ChronoLocalDateTimeSerialization(Chronology chrono) throws Exception { 325 LocalDateTime ref = LocalDate.of(2000, 1, 5).atTime(12, 1, 2, 3); 326 ChronoLocalDateTime<?> orginal = chrono.date(ref).atTime(ref.toLocalTime()); 327 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 328 ObjectOutputStream out = new ObjectOutputStream(baos); 329 out.writeObject(orginal); 330 out.close(); 331 ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); 332 ObjectInputStream in = new ObjectInputStream(bais); 333 ChronoLocalDateTime<?> ser = (ChronoLocalDateTime<?>) in.readObject(); 334 assertEquals(ser, orginal, "deserialized date is wrong"); 335 } 336 337 338 /** 339 * FixedAdjusted returns a fixed Temporal in all adjustments. 340 * Construct an adjuster with the Temporal that should be returned from adjust. 341 */ 342 static class FixedAdjuster implements TemporalAdjuster, TemporalAmount { 343 private Temporal datetime; 344 345 FixedAdjuster(Temporal datetime) { 346 this.datetime = datetime; 347 } 348 349 @Override 350 public Temporal adjustInto(Temporal ignore) { 351 return datetime; 352 } 353 354 @Override 355 public Temporal addTo(Temporal ignore) { 356 return datetime; 357 } 358 359 @Override 360 public Temporal subtractFrom(Temporal ignore) { 361 return datetime; 362 } 363 364 @Override 365 public long get(TemporalUnit unit) { 366 throw new UnsupportedOperationException("Not supported yet."); 367 } 368 369 @Override 370 public List<TemporalUnit> getUnits() { 371 throw new UnsupportedOperationException("Not supported yet."); 372 } 373 374 } 375 376 /** 377 * FixedTemporalUnit returns a fixed Temporal in all adjustments. 378 * Construct an FixedTemporalUnit with the Temporal that should be returned from doAdd. 379 */ 380 static class FixedTemporalUnit implements TemporalUnit { 381 private Temporal temporal; 382 383 FixedTemporalUnit(Temporal temporal) { 384 this.temporal = temporal; 385 } 386 387 @Override 388 public String getName() { 389 return "FixedTemporalUnit"; 390 } 391 392 @Override 393 public Duration getDuration() { 394 throw new UnsupportedOperationException("Not supported yet."); 395 } 396 397 @Override 398 public boolean isDurationEstimated() { 399 throw new UnsupportedOperationException("Not supported yet."); 400 } 401 402 @Override 403 public boolean isSupportedBy(Temporal temporal) { 404 throw new UnsupportedOperationException("Not supported yet."); 405 } 406 407 @SuppressWarnings("unchecked") 408 @Override 409 public <R extends Temporal> R addTo(R temporal, long amount) { 410 return (R) this.temporal; 411 } 412 413 @Override 414 public long between(Temporal temporal1, Temporal temporal2) { 415 throw new UnsupportedOperationException("Not supported yet."); 416 } 417 } 418 419 /** 420 * FixedTemporalField returns a fixed Temporal in all adjustments. 421 * Construct an FixedTemporalField with the Temporal that should be returned from doSet. 422 */ 423 static class FixedTemporalField implements TemporalField { 424 private Temporal temporal; 425 FixedTemporalField(Temporal temporal) { 426 this.temporal = temporal; 427 } 428 429 @Override 430 public String getName() { 431 return "FixedTemporalField"; 432 } 433 434 @Override 435 public TemporalUnit getBaseUnit() { 436 throw new UnsupportedOperationException("Not supported yet."); 437 } 438 439 @Override 440 public TemporalUnit getRangeUnit() { 441 throw new UnsupportedOperationException("Not supported yet."); 442 } 443 444 @Override 445 public ValueRange range() { 446 throw new UnsupportedOperationException("Not supported yet."); 447 } 448 449 @Override 450 public boolean isSupportedBy(TemporalAccessor temporal) { 451 throw new UnsupportedOperationException("Not supported yet."); 452 } 453 454 @Override 455 public ValueRange rangeRefinedBy(TemporalAccessor temporal) { 456 throw new UnsupportedOperationException("Not supported yet."); 457 } 458 459 @Override 460 public long getFrom(TemporalAccessor temporal) { 461 throw new UnsupportedOperationException("Not supported yet."); 462 } 463 464 @SuppressWarnings("unchecked") 465 @Override 466 public <R extends Temporal> R adjustInto(R temporal, long newValue) { 467 return (R) this.temporal; 468 } 469 } 470 } |