1 /*
   2  * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * This file is available under and governed by the GNU General Public
  26  * License version 2 only, as published by the Free Software Foundation.
  27  * However, the following notice accompanied the original version of this
  28  * file:
  29  *
  30  * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos
  31  *
  32  * All rights reserved.
  33  *
  34  * Redistribution and use in source and binary forms, with or without
  35  * modification, are permitted provided that the following conditions are met:
  36  *
  37  *  * Redistributions of source code must retain the above copyright notice,
  38  *    this list of conditions and the following disclaimer.
  39  *
  40  *  * Redistributions in binary form must reproduce the above copyright notice,
  41  *    this list of conditions and the following disclaimer in the documentation
  42  *    and/or other materials provided with the distribution.
  43  *
  44  *  * Neither the name of JSR-310 nor the names of its contributors
  45  *    may be used to endorse or promote products derived from this software
  46  *    without specific prior written permission.
  47  *
  48  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  49  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  50  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  51  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  52  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  53  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  54  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  55  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  56  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  57  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  58  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  59  */
  60 package tck.java.time;
  61 
  62 import static java.time.temporal.ChronoField.ERA;
  63 import static java.time.temporal.ChronoField.YEAR;
  64 import static java.time.temporal.ChronoField.YEAR_OF_ERA;
  65 import static org.testng.Assert.assertEquals;
  66 import static org.testng.Assert.fail;
  67 
  68 import java.io.ByteArrayOutputStream;
  69 import java.io.DataOutputStream;
  70 import java.time.Clock;
  71 import java.time.DateTimeException;
  72 import java.time.Instant;
  73 import java.time.LocalDate;
  74 import java.time.LocalTime;
  75 import java.time.Month;
  76 import java.time.MonthDay;
  77 import java.time.OffsetDateTime;
  78 import java.time.Year;
  79 import java.time.YearMonth;
  80 import java.time.ZoneId;
  81 import java.time.ZoneOffset;
  82 import java.time.chrono.IsoChronology;
  83 import java.time.format.DateTimeFormatter;
  84 import java.time.format.DateTimeParseException;
  85 import java.time.temporal.ChronoField;
  86 import java.time.temporal.ChronoUnit;
  87 import java.time.temporal.JulianFields;
  88 import java.time.temporal.Queries;
  89 import java.time.temporal.Temporal;
  90 import java.time.temporal.TemporalAccessor;
  91 import java.time.temporal.TemporalField;
  92 import java.time.temporal.TemporalQuery;
  93 import java.util.ArrayList;
  94 import java.util.Arrays;
  95 import java.util.List;
  96 
  97 import org.testng.annotations.BeforeMethod;
  98 import org.testng.annotations.DataProvider;
  99 import org.testng.annotations.Test;
 100 
 101 /**
 102  * Test Year.
 103  */
 104 @Test
 105 public class TCKYear extends AbstractDateTimeTest {
 106 
 107     private static final Year TEST_2008 = Year.of(2008);
 108 
 109     @BeforeMethod
 110     public void setUp() {
 111     }
 112 
 113     //-----------------------------------------------------------------------
 114     @Override
 115     protected List<TemporalAccessor> samples() {
 116         TemporalAccessor[] array = {TEST_2008, };
 117         return Arrays.asList(array);
 118     }
 119 
 120     @Override
 121     protected List<TemporalField> validFields() {
 122         TemporalField[] array = {
 123             YEAR_OF_ERA,
 124             YEAR,
 125             ERA,
 126         };
 127         return Arrays.asList(array);
 128     }
 129 
 130     @Override
 131     protected List<TemporalField> invalidFields() {
 132         List<TemporalField> list = new ArrayList<>(Arrays.<TemporalField>asList(ChronoField.values()));
 133         list.removeAll(validFields());
 134         list.add(JulianFields.JULIAN_DAY);
 135         list.add(JulianFields.MODIFIED_JULIAN_DAY);
 136         list.add(JulianFields.RATA_DIE);
 137         return list;
 138     }
 139 
 140     //-----------------------------------------------------------------------
 141     @Test
 142     public void test_serialization() throws Exception {
 143         assertSerializable(Year.of(2));
 144         assertSerializable(Year.of(0));
 145         assertSerializable(Year.of(-2));
 146     }
 147 
 148     @Test
 149     public void test_serialization_format() throws Exception {
 150         ByteArrayOutputStream baos = new ByteArrayOutputStream();
 151         try (DataOutputStream dos = new DataOutputStream(baos) ) {
 152             dos.writeByte(11);       // java.time.temporal.Ser.YEAR_TYPE
 153             dos.writeInt(2012);
 154         }
 155         byte[] bytes = baos.toByteArray();
 156         assertSerializedBySer(Year.of(2012), bytes);
 157     }
 158 
 159     //-----------------------------------------------------------------------
 160     // now()
 161     //-----------------------------------------------------------------------
 162     @Test(groups={"tck"})
 163     public void now() {
 164         Year expected = Year.now(Clock.systemDefaultZone());
 165         Year test = Year.now();
 166         for (int i = 0; i < 100; i++) {
 167             if (expected.equals(test)) {
 168                 return;
 169             }
 170             expected = Year.now(Clock.systemDefaultZone());
 171             test = Year.now();
 172         }
 173         assertEquals(test, expected);
 174     }
 175 
 176     //-----------------------------------------------------------------------
 177     // now(ZoneId)
 178     //-----------------------------------------------------------------------
 179     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
 180     public void now_ZoneId_nullZoneId() {
 181         Year.now((ZoneId) null);
 182     }
 183 
 184     @Test(groups={"tck"})
 185     public void now_ZoneId() {
 186         ZoneId zone = ZoneId.of("UTC+01:02:03");
 187         Year expected = Year.now(Clock.system(zone));
 188         Year test = Year.now(zone);
 189         for (int i = 0; i < 100; i++) {
 190             if (expected.equals(test)) {
 191                 return;
 192             }
 193             expected = Year.now(Clock.system(zone));
 194             test = Year.now(zone);
 195         }
 196         assertEquals(test, expected);
 197     }
 198 
 199     //-----------------------------------------------------------------------
 200     // now(Clock)
 201     //-----------------------------------------------------------------------
 202     @Test(groups={"tck"})
 203     public void now_Clock() {
 204         Instant instant = OffsetDateTime.of(LocalDate.of(2010, 12, 31), LocalTime.of(0, 0), ZoneOffset.UTC).toInstant();
 205         Clock clock = Clock.fixed(instant, ZoneOffset.UTC);
 206         Year test = Year.now(clock);
 207         assertEquals(test.getValue(), 2010);
 208     }
 209 
 210     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
 211     public void now_Clock_nullClock() {
 212         Year.now((Clock) null);
 213     }
 214 
 215     //-----------------------------------------------------------------------
 216     @Test(groups={"tck"})
 217     public void test_factory_int_singleton() {
 218         for (int i = -4; i <= 2104; i++) {
 219             Year test = Year.of(i);
 220             assertEquals(test.getValue(), i);
 221             assertEquals(Year.of(i), test);
 222         }
 223     }
 224 
 225     @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
 226     public void test_factory_int_tooLow() {
 227         Year.of(Year.MIN_VALUE - 1);
 228     }
 229 
 230     @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
 231     public void test_factory_int_tooHigh() {
 232         Year.of(Year.MAX_VALUE + 1);
 233     }
 234 
 235     //-----------------------------------------------------------------------
 236     @Test(groups={"tck"})
 237     public void test_factory_CalendricalObject() {
 238         assertEquals(Year.from(LocalDate.of(2007, 7, 15)), Year.of(2007));
 239     }
 240 
 241     @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
 242     public void test_factory_CalendricalObject_invalid_noDerive() {
 243         Year.from(LocalTime.of(12, 30));
 244     }
 245 
 246     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
 247     public void test_factory_CalendricalObject_null() {
 248         Year.from((TemporalAccessor) null);
 249     }
 250 
 251     //-----------------------------------------------------------------------
 252     // parse()
 253     //-----------------------------------------------------------------------
 254     @DataProvider(name="goodParseData")
 255     Object[][] provider_goodParseData() {
 256         return new Object[][] {
 257                 {"0000", Year.of(0)},
 258                 {"9999", Year.of(9999)},
 259                 {"2000", Year.of(2000)},
 260 
 261                 {"+12345678", Year.of(12345678)},
 262                 {"+123456", Year.of(123456)},
 263                 {"-1234", Year.of(-1234)},
 264                 {"-12345678", Year.of(-12345678)},
 265 
 266                 {"+" + Year.MAX_VALUE, Year.of(Year.MAX_VALUE)},
 267                 {"" + Year.MIN_VALUE, Year.of(Year.MIN_VALUE)},
 268         };
 269     }
 270 
 271     @Test(dataProvider="goodParseData", groups={"tck"})
 272     public void factory_parse_success(String text, Year expected) {
 273         Year year = Year.parse(text);
 274         assertEquals(year, expected);
 275     }
 276 
 277     @DataProvider(name="badParseData")
 278     Object[][] provider_badParseData() {
 279         return new Object[][] {
 280                 {"", 0},
 281                 {"-00", 1},
 282                 {"--01-0", 1},
 283                 {"A01", 0},
 284                 {"200", 0},
 285                 {"2009/12", 4},
 286 
 287                 {"-0000-10", 0},
 288                 {"-12345678901-10", 11},
 289                 {"+1-10", 1},
 290                 {"+12-10", 1},
 291                 {"+123-10", 1},
 292                 {"+1234-10", 0},
 293                 {"12345-10", 0},
 294                 {"+12345678901-10", 11},
 295         };
 296     }
 297 
 298     @Test(dataProvider="badParseData", expectedExceptions=DateTimeParseException.class, groups={"tck"})
 299     public void factory_parse_fail(String text, int pos) {
 300         try {
 301             Year.parse(text);
 302             fail(String.format("Parse should have failed for %s at position %d", text, pos));
 303         } catch (DateTimeParseException ex) {
 304             assertEquals(ex.getParsedString(), text);
 305             assertEquals(ex.getErrorIndex(), pos);
 306             throw ex;
 307         }
 308     }
 309 
 310     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
 311     public void factory_parse_nullText() {
 312         Year.parse(null);
 313     }
 314 
 315     //-----------------------------------------------------------------------
 316     // parse(DateTimeFormatter)
 317     //-----------------------------------------------------------------------
 318     @Test(groups={"tck"})
 319     public void factory_parse_formatter() {
 320         DateTimeFormatter f = DateTimeFormatter.ofPattern("y");
 321         Year test = Year.parse("2010", f);
 322         assertEquals(test, Year.of(2010));
 323     }
 324 
 325     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
 326     public void factory_parse_formatter_nullText() {
 327         DateTimeFormatter f = DateTimeFormatter.ofPattern("y");
 328         Year.parse((String) null, f);
 329     }
 330 
 331     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
 332     public void factory_parse_formatter_nullFormatter() {
 333         Year.parse("ANY", null);
 334     }
 335 
 336     //-----------------------------------------------------------------------
 337     // get(TemporalField)
 338     //-----------------------------------------------------------------------
 339     @Test
 340     public void test_get_TemporalField() {
 341         assertEquals(TEST_2008.get(ChronoField.YEAR), 2008);
 342         assertEquals(TEST_2008.get(ChronoField.YEAR_OF_ERA), 2008);
 343         assertEquals(TEST_2008.get(ChronoField.ERA), 1);
 344     }
 345 
 346     @Test
 347     public void test_getLong_TemporalField() {
 348         assertEquals(TEST_2008.getLong(ChronoField.YEAR), 2008);
 349         assertEquals(TEST_2008.getLong(ChronoField.YEAR_OF_ERA), 2008);
 350         assertEquals(TEST_2008.getLong(ChronoField.ERA), 1);
 351     }
 352 
 353     //-----------------------------------------------------------------------
 354     // query(TemporalQuery)
 355     //-----------------------------------------------------------------------
 356     @DataProvider(name="query")
 357     Object[][] data_query() {
 358         return new Object[][] {
 359                 {TEST_2008, Queries.chronology(), IsoChronology.INSTANCE},
 360                 {TEST_2008, Queries.zoneId(), null},
 361                 {TEST_2008, Queries.precision(), ChronoUnit.YEARS},
 362                 {TEST_2008, Queries.zone(), null},
 363                 {TEST_2008, Queries.offset(), null},
 364                 {TEST_2008, Queries.localDate(), null},
 365                 {TEST_2008, Queries.localTime(), null},
 366         };
 367     }
 368 
 369     @Test(dataProvider="query")
 370     public <T> void test_query(TemporalAccessor temporal, TemporalQuery<T> query, T expected) {
 371         assertEquals(temporal.query(query), expected);
 372     }
 373 
 374     @Test(dataProvider="query")
 375     public <T> void test_queryFrom(TemporalAccessor temporal, TemporalQuery<T> query, T expected) {
 376         assertEquals(query.queryFrom(temporal), expected);
 377     }
 378 
 379     @Test(expectedExceptions=NullPointerException.class)
 380     public void test_query_null() {
 381         TEST_2008.query(null);
 382     }
 383 
 384     //-----------------------------------------------------------------------
 385     // isLeap()
 386     //-----------------------------------------------------------------------
 387     @Test(groups={"tck"})
 388     public void test_isLeap() {
 389         assertEquals(Year.of(1999).isLeap(), false);
 390         assertEquals(Year.of(2000).isLeap(), true);
 391         assertEquals(Year.of(2001).isLeap(), false);
 392 
 393         assertEquals(Year.of(2007).isLeap(), false);
 394         assertEquals(Year.of(2008).isLeap(), true);
 395         assertEquals(Year.of(2009).isLeap(), false);
 396         assertEquals(Year.of(2010).isLeap(), false);
 397         assertEquals(Year.of(2011).isLeap(), false);
 398         assertEquals(Year.of(2012).isLeap(), true);
 399 
 400         assertEquals(Year.of(2095).isLeap(), false);
 401         assertEquals(Year.of(2096).isLeap(), true);
 402         assertEquals(Year.of(2097).isLeap(), false);
 403         assertEquals(Year.of(2098).isLeap(), false);
 404         assertEquals(Year.of(2099).isLeap(), false);
 405         assertEquals(Year.of(2100).isLeap(), false);
 406         assertEquals(Year.of(2101).isLeap(), false);
 407         assertEquals(Year.of(2102).isLeap(), false);
 408         assertEquals(Year.of(2103).isLeap(), false);
 409         assertEquals(Year.of(2104).isLeap(), true);
 410         assertEquals(Year.of(2105).isLeap(), false);
 411 
 412         assertEquals(Year.of(-500).isLeap(), false);
 413         assertEquals(Year.of(-400).isLeap(), true);
 414         assertEquals(Year.of(-300).isLeap(), false);
 415         assertEquals(Year.of(-200).isLeap(), false);
 416         assertEquals(Year.of(-100).isLeap(), false);
 417         assertEquals(Year.of(0).isLeap(), true);
 418         assertEquals(Year.of(100).isLeap(), false);
 419         assertEquals(Year.of(200).isLeap(), false);
 420         assertEquals(Year.of(300).isLeap(), false);
 421         assertEquals(Year.of(400).isLeap(), true);
 422         assertEquals(Year.of(500).isLeap(), false);
 423     }
 424 
 425     //-----------------------------------------------------------------------
 426     // plusYears()
 427     //-----------------------------------------------------------------------
 428     @Test(groups={"tck"})
 429     public void test_plusYears() {
 430         assertEquals(Year.of(2007).plusYears(-1), Year.of(2006));
 431         assertEquals(Year.of(2007).plusYears(0), Year.of(2007));
 432         assertEquals(Year.of(2007).plusYears(1), Year.of(2008));
 433         assertEquals(Year.of(2007).plusYears(2), Year.of(2009));
 434 
 435         assertEquals(Year.of(Year.MAX_VALUE - 1).plusYears(1), Year.of(Year.MAX_VALUE));
 436         assertEquals(Year.of(Year.MAX_VALUE).plusYears(0), Year.of(Year.MAX_VALUE));
 437 
 438         assertEquals(Year.of(Year.MIN_VALUE + 1).plusYears(-1), Year.of(Year.MIN_VALUE));
 439         assertEquals(Year.of(Year.MIN_VALUE).plusYears(0), Year.of(Year.MIN_VALUE));
 440     }
 441 
 442     @Test(groups={"tck"})
 443     public void test_plusYear_zero_equals() {
 444         Year base = Year.of(2007);
 445         assertEquals(base.plusYears(0), base);
 446     }
 447 
 448     @Test(groups={"tck"})
 449     public void test_plusYears_big() {
 450         long years = 20L + Year.MAX_VALUE;
 451         assertEquals(Year.of(-40).plusYears(years), Year.of((int) (-40L + years)));
 452     }
 453 
 454     @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
 455     public void test_plusYears_max() {
 456         Year.of(Year.MAX_VALUE).plusYears(1);
 457     }
 458 
 459     @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
 460     public void test_plusYears_maxLots() {
 461         Year.of(Year.MAX_VALUE).plusYears(1000);
 462     }
 463 
 464     @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
 465     public void test_plusYears_min() {
 466         Year.of(Year.MIN_VALUE).plusYears(-1);
 467     }
 468 
 469     @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
 470     public void test_plusYears_minLots() {
 471         Year.of(Year.MIN_VALUE).plusYears(-1000);
 472     }
 473 
 474     //-----------------------------------------------------------------------
 475     // minusYears()
 476     //-----------------------------------------------------------------------
 477     @Test(groups={"tck"})
 478     public void test_minusYears() {
 479         assertEquals(Year.of(2007).minusYears(-1), Year.of(2008));
 480         assertEquals(Year.of(2007).minusYears(0), Year.of(2007));
 481         assertEquals(Year.of(2007).minusYears(1), Year.of(2006));
 482         assertEquals(Year.of(2007).minusYears(2), Year.of(2005));
 483 
 484         assertEquals(Year.of(Year.MAX_VALUE - 1).minusYears(-1), Year.of(Year.MAX_VALUE));
 485         assertEquals(Year.of(Year.MAX_VALUE).minusYears(0), Year.of(Year.MAX_VALUE));
 486 
 487         assertEquals(Year.of(Year.MIN_VALUE + 1).minusYears(1), Year.of(Year.MIN_VALUE));
 488         assertEquals(Year.of(Year.MIN_VALUE).minusYears(0), Year.of(Year.MIN_VALUE));
 489     }
 490 
 491     @Test(groups={"tck"})
 492     public void test_minusYear_zero_equals() {
 493         Year base = Year.of(2007);
 494         assertEquals(base.minusYears(0), base);
 495     }
 496 
 497     @Test(groups={"tck"})
 498     public void test_minusYears_big() {
 499         long years = 20L + Year.MAX_VALUE;
 500         assertEquals(Year.of(40).minusYears(years), Year.of((int) (40L - years)));
 501     }
 502 
 503     @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
 504     public void test_minusYears_max() {
 505         Year.of(Year.MAX_VALUE).minusYears(-1);
 506     }
 507 
 508     @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
 509     public void test_minusYears_maxLots() {
 510         Year.of(Year.MAX_VALUE).minusYears(-1000);
 511     }
 512 
 513     @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
 514     public void test_minusYears_min() {
 515         Year.of(Year.MIN_VALUE).minusYears(1);
 516     }
 517 
 518     @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
 519     public void test_minusYears_minLots() {
 520         Year.of(Year.MIN_VALUE).minusYears(1000);
 521     }
 522 
 523     //-----------------------------------------------------------------------
 524     // adjustInto()
 525     //-----------------------------------------------------------------------
 526     @Test(groups={"tck"})
 527     public void test_adjustDate() {
 528         LocalDate base = LocalDate.of(2007, 2, 12);
 529         for (int i = -4; i <= 2104; i++) {
 530             Temporal result = Year.of(i).adjustInto(base);
 531             assertEquals(result, LocalDate.of(i, 2, 12));
 532         }
 533     }
 534 
 535     @Test(groups={"tck"})
 536     public void test_adjustDate_resolve() {
 537         Year test = Year.of(2011);
 538         assertEquals(test.adjustInto(LocalDate.of(2012, 2, 29)), LocalDate.of(2011, 2, 28));
 539     }
 540 
 541     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
 542     public void test_adjustDate_nullLocalDate() {
 543         Year test = Year.of(1);
 544         test.adjustInto((LocalDate) null);
 545     }
 546 
 547     //-----------------------------------------------------------------------
 548     // length()
 549     //-----------------------------------------------------------------------
 550     @Test(groups={"tck"})
 551     public void test_length() {
 552         assertEquals(Year.of(1999).length(), 365);
 553         assertEquals(Year.of(2000).length(), 366);
 554         assertEquals(Year.of(2001).length(), 365);
 555 
 556         assertEquals(Year.of(2007).length(), 365);
 557         assertEquals(Year.of(2008).length(), 366);
 558         assertEquals(Year.of(2009).length(), 365);
 559         assertEquals(Year.of(2010).length(), 365);
 560         assertEquals(Year.of(2011).length(), 365);
 561         assertEquals(Year.of(2012).length(), 366);
 562 
 563         assertEquals(Year.of(2095).length(), 365);
 564         assertEquals(Year.of(2096).length(), 366);
 565         assertEquals(Year.of(2097).length(), 365);
 566         assertEquals(Year.of(2098).length(), 365);
 567         assertEquals(Year.of(2099).length(), 365);
 568         assertEquals(Year.of(2100).length(), 365);
 569         assertEquals(Year.of(2101).length(), 365);
 570         assertEquals(Year.of(2102).length(), 365);
 571         assertEquals(Year.of(2103).length(), 365);
 572         assertEquals(Year.of(2104).length(), 366);
 573         assertEquals(Year.of(2105).length(), 365);
 574 
 575         assertEquals(Year.of(-500).length(), 365);
 576         assertEquals(Year.of(-400).length(), 366);
 577         assertEquals(Year.of(-300).length(), 365);
 578         assertEquals(Year.of(-200).length(), 365);
 579         assertEquals(Year.of(-100).length(), 365);
 580         assertEquals(Year.of(0).length(), 366);
 581         assertEquals(Year.of(100).length(), 365);
 582         assertEquals(Year.of(200).length(), 365);
 583         assertEquals(Year.of(300).length(), 365);
 584         assertEquals(Year.of(400).length(), 366);
 585         assertEquals(Year.of(500).length(), 365);
 586     }
 587 
 588     //-----------------------------------------------------------------------
 589     // isValidMonthDay(MonthDay)
 590     //-----------------------------------------------------------------------
 591     @DataProvider(name="isValidMonthDay")
 592     Object[][] data_isValidMonthDay() {
 593         return new Object[][] {
 594                 {Year.of(2007), MonthDay.of(6, 30), true},
 595                 {Year.of(2008), MonthDay.of(2, 28), true},
 596                 {Year.of(2008), MonthDay.of(2, 29), true},
 597                 {Year.of(2009), MonthDay.of(2, 28), true},
 598                 {Year.of(2009), MonthDay.of(2, 29), false},
 599                 {Year.of(2009), null, false},
 600         };
 601     }
 602 
 603     @Test(dataProvider="isValidMonthDay")
 604     public void test_isValidMonthDay(Year year, MonthDay monthDay, boolean expected) {
 605         assertEquals(year.isValidMonthDay(monthDay), expected);
 606     }
 607 
 608     //-----------------------------------------------------------------------
 609     // atMonth(Month)
 610     //-----------------------------------------------------------------------
 611     @Test
 612     public void test_atMonth() {
 613         Year test = Year.of(2008);
 614         assertEquals(test.atMonth(Month.JUNE), YearMonth.of(2008, 6));
 615     }
 616 
 617     @Test(expectedExceptions=NullPointerException.class)
 618     public void test_atMonth_nullMonth() {
 619         Year test = Year.of(2008);
 620         test.atMonth((Month) null);
 621     }
 622 
 623     //-----------------------------------------------------------------------
 624     // atMonth(int)
 625     //-----------------------------------------------------------------------
 626     @Test
 627     public void test_atMonth_int() {
 628         Year test = Year.of(2008);
 629         assertEquals(test.atMonth(6), YearMonth.of(2008, 6));
 630     }
 631 
 632     @Test(expectedExceptions=DateTimeException.class)
 633     public void test_atMonth_int_invalidMonth() {
 634         Year test = Year.of(2008);
 635         test.atMonth(13);
 636     }
 637 
 638     //-----------------------------------------------------------------------
 639     // atMonthDay(Month)
 640     //-----------------------------------------------------------------------
 641     @DataProvider(name="atMonthDay")
 642     Object[][] data_atMonthDay() {
 643         return new Object[][] {
 644                 {Year.of(2008), MonthDay.of(6, 30), LocalDate.of(2008, 6, 30)},
 645                 {Year.of(2008), MonthDay.of(2, 29), LocalDate.of(2008, 2, 29)},
 646                 {Year.of(2009), MonthDay.of(2, 29), LocalDate.of(2009, 2, 28)},
 647         };
 648     }
 649 
 650     @Test(dataProvider="atMonthDay")
 651     public void test_atMonthDay(Year year, MonthDay monthDay, LocalDate expected) {
 652         assertEquals(year.atMonthDay(monthDay), expected);
 653     }
 654 
 655     @Test(expectedExceptions=NullPointerException.class)
 656     public void test_atMonthDay_nullMonthDay() {
 657         Year test = Year.of(2008);
 658         test.atMonthDay((MonthDay) null);
 659     }
 660 
 661     //-----------------------------------------------------------------------
 662     // atDay(int)
 663     //-----------------------------------------------------------------------
 664     @Test(groups={"tck"})
 665     public void test_atDay_notLeapYear() {
 666         Year test = Year.of(2007);
 667         LocalDate expected = LocalDate.of(2007, 1, 1);
 668         for (int i = 1; i <= 365; i++) {
 669             assertEquals(test.atDay(i), expected);
 670             expected = expected.plusDays(1);
 671         }
 672     }
 673 
 674     @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
 675     public void test_atDay_notLeapYear_day366() {
 676         Year test = Year.of(2007);
 677         test.atDay(366);
 678     }
 679 
 680     @Test(groups={"tck"})
 681     public void test_atDay_leapYear() {
 682         Year test = Year.of(2008);
 683         LocalDate expected = LocalDate.of(2008, 1, 1);
 684         for (int i = 1; i <= 366; i++) {
 685             assertEquals(test.atDay(i), expected);
 686             expected = expected.plusDays(1);
 687         }
 688     }
 689 
 690     @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
 691     public void test_atDay_day0() {
 692         Year test = Year.of(2007);
 693         test.atDay(0);
 694     }
 695 
 696     @Test(expectedExceptions=DateTimeException.class, groups={"tck"})
 697     public void test_atDay_day367() {
 698         Year test = Year.of(2007);
 699         test.atDay(367);
 700     }
 701 
 702     //-----------------------------------------------------------------------
 703     // compareTo()
 704     //-----------------------------------------------------------------------
 705     @Test(groups={"tck"})
 706     public void test_compareTo() {
 707         for (int i = -4; i <= 2104; i++) {
 708             Year a = Year.of(i);
 709             for (int j = -4; j <= 2104; j++) {
 710                 Year b = Year.of(j);
 711                 if (i < j) {
 712                     assertEquals(a.compareTo(b) < 0, true);
 713                     assertEquals(b.compareTo(a) > 0, true);
 714                     assertEquals(a.isAfter(b), false);
 715                     assertEquals(a.isBefore(b), true);
 716                     assertEquals(b.isAfter(a), true);
 717                     assertEquals(b.isBefore(a), false);
 718                 } else if (i > j) {
 719                     assertEquals(a.compareTo(b) > 0, true);
 720                     assertEquals(b.compareTo(a) < 0, true);
 721                     assertEquals(a.isAfter(b), true);
 722                     assertEquals(a.isBefore(b), false);
 723                     assertEquals(b.isAfter(a), false);
 724                     assertEquals(b.isBefore(a), true);
 725                 } else {
 726                     assertEquals(a.compareTo(b), 0);
 727                     assertEquals(b.compareTo(a), 0);
 728                     assertEquals(a.isAfter(b), false);
 729                     assertEquals(a.isBefore(b), false);
 730                     assertEquals(b.isAfter(a), false);
 731                     assertEquals(b.isBefore(a), false);
 732                 }
 733             }
 734         }
 735     }
 736 
 737     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
 738     public void test_compareTo_nullYear() {
 739         Year doy = null;
 740         Year test = Year.of(1);
 741         test.compareTo(doy);
 742     }
 743 
 744     //-----------------------------------------------------------------------
 745     // equals() / hashCode()
 746     //-----------------------------------------------------------------------
 747     @Test(groups={"tck"})
 748     public void test_equals() {
 749         for (int i = -4; i <= 2104; i++) {
 750             Year a = Year.of(i);
 751             for (int j = -4; j <= 2104; j++) {
 752                 Year b = Year.of(j);
 753                 assertEquals(a.equals(b), i == j);
 754                 assertEquals(a.hashCode() == b.hashCode(), i == j);
 755             }
 756         }
 757     }
 758 
 759     @Test(groups={"tck"})
 760     public void test_equals_same() {
 761         Year test = Year.of(2011);
 762         assertEquals(test.equals(test), true);
 763     }
 764 
 765     @Test(groups={"tck"})
 766     public void test_equals_nullYear() {
 767         Year doy = null;
 768         Year test = Year.of(1);
 769         assertEquals(test.equals(doy), false);
 770     }
 771 
 772     @Test(groups={"tck"})
 773     public void test_equals_incorrectType() {
 774         Year test = Year.of(1);
 775         assertEquals(test.equals("Incorrect type"), false);
 776     }
 777 
 778     //-----------------------------------------------------------------------
 779     // toString()
 780     //-----------------------------------------------------------------------
 781     @Test(groups={"tck"})
 782     public void test_toString() {
 783         for (int i = -4; i <= 2104; i++) {
 784             Year a = Year.of(i);
 785             assertEquals(a.toString(), "" + i);
 786         }
 787     }
 788 
 789     //-----------------------------------------------------------------------
 790     // toString(DateTimeFormatter)
 791     //-----------------------------------------------------------------------
 792     @Test(groups={"tck"})
 793     public void test_toString_formatter() {
 794         DateTimeFormatter f = DateTimeFormatter.ofPattern("y");
 795         String t = Year.of(2010).toString(f);
 796         assertEquals(t, "2010");
 797     }
 798 
 799     @Test(expectedExceptions=NullPointerException.class, groups={"tck"})
 800     public void test_toString_formatter_null() {
 801         Year.of(2010).toString(null);
 802     }
 803 
 804 }