001/* 002 * Copyright (c) 2007-2013, Stephen Colebourne & Michael Nascimento Santos 003 * 004 * All rights reserved. 005 * 006 * Redistribution and use in source and binary forms, with or without 007 * modification, are permitted provided that the following conditions are met: 008 * 009 * * Redistributions of source code must retain the above copyright notice, 010 * this list of conditions and the following disclaimer. 011 * 012 * * Redistributions in binary form must reproduce the above copyright notice, 013 * this list of conditions and the following disclaimer in the documentation 014 * and/or other materials provided with the distribution. 015 * 016 * * Neither the name of JSR-310 nor the names of its contributors 017 * may be used to endorse or promote products derived from this software 018 * without specific prior written permission. 019 * 020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 021 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 022 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 023 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 024 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 025 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 026 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 027 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 028 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 029 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 030 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 031 */ 032package org.threeten.bp; 033 034import static org.threeten.bp.temporal.ChronoField.ERA; 035import static org.threeten.bp.temporal.ChronoField.YEAR; 036import static org.threeten.bp.temporal.ChronoField.YEAR_OF_ERA; 037import static org.threeten.bp.temporal.ChronoUnit.YEARS; 038 039import java.io.DataInput; 040import java.io.DataOutput; 041import java.io.IOException; 042import java.io.InvalidObjectException; 043import java.io.ObjectStreamException; 044import java.io.Serializable; 045import java.util.Objects; 046 047import org.threeten.bp.format.DateTimeFormatter; 048import org.threeten.bp.format.DateTimeFormatterBuilder; 049import org.threeten.bp.format.DateTimeParseException; 050import org.threeten.bp.format.SignStyle; 051import org.threeten.bp.jdk8.DefaultInterfaceTemporalAccessor; 052import org.threeten.bp.jdk8.Jdk8Methods; 053import org.threeten.bp.temporal.Chrono; 054import org.threeten.bp.temporal.ChronoField; 055import org.threeten.bp.temporal.ChronoUnit; 056import org.threeten.bp.temporal.ISOChrono; 057import org.threeten.bp.temporal.Temporal; 058import org.threeten.bp.temporal.TemporalAccessor; 059import org.threeten.bp.temporal.TemporalAdder; 060import org.threeten.bp.temporal.TemporalAdjuster; 061import org.threeten.bp.temporal.TemporalField; 062import org.threeten.bp.temporal.TemporalQueries; 063import org.threeten.bp.temporal.TemporalQuery; 064import org.threeten.bp.temporal.TemporalSubtractor; 065import org.threeten.bp.temporal.TemporalUnit; 066import org.threeten.bp.temporal.ValueRange; 067 068/** 069 * A year in the ISO-8601 calendar system, such as {@code 2007}. 070 * <p> 071 * {@code Year} is an immutable date-time object that represents a year. 072 * Any field that can be derived from a year can be obtained. 073 * <p> 074 * <b>Note that years in the ISO chronology only align with years in the 075 * Gregorian-Julian system for modern years. Parts of Russia did not switch to the 076 * modern Gregorian/ISO rules until 1920. 077 * As such, historical years must be treated with caution.</b> 078 * <p> 079 * This class does not store or represent a month, day, time or time-zone. 080 * For example, the value "2007" can be stored in a {@code Year}. 081 * <p> 082 * Years represented by this class follow the ISO-8601 standard and use 083 * the proleptic numbering system. Year 1 is preceded by year 0, then by year -1. 084 * <p> 085 * The ISO-8601 calendar system is the modern civil calendar system used today 086 * in most of the world. It is equivalent to the proleptic Gregorian calendar 087 * system, in which todays's rules for leap years are applied for all time. 088 * For most applications written today, the ISO-8601 rules are entirely suitable. 089 * Any application that uses historical dates should consider using {@code HistoricDate}. 090 * 091 * <h3>Specification for implementors</h3> 092 * This class is immutable and thread-safe. 093 */ 094public final class Year 095 extends DefaultInterfaceTemporalAccessor 096 implements Temporal, TemporalAdjuster, Comparable<Year>, Serializable { 097 098 /** 099 * The minimum supported year, '-999,999,999'. 100 */ 101 public static final int MIN_VALUE = -999_999_999; 102 /** 103 * The maximum supported year, '+999,999,999'. 104 */ 105 public static final int MAX_VALUE = 999_999_999; 106 107 /** 108 * Serialization version. 109 */ 110 private static final long serialVersionUID = -23038383694477807L; 111 /** 112 * Parser. 113 */ 114 private static final DateTimeFormatter PARSER = new DateTimeFormatterBuilder() 115 .appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD) 116 .toFormatter(); 117 118 /** 119 * The year being represented. 120 */ 121 private final int year; 122 123 //----------------------------------------------------------------------- 124 /** 125 * Obtains the current year from the system clock in the default time-zone. 126 * <p> 127 * This will query the {@link Clock#systemDefaultZone() system clock} in the default 128 * time-zone to obtain the current year. 129 * <p> 130 * Using this method will prevent the ability to use an alternate clock for testing 131 * because the clock is hard-coded. 132 * 133 * @return the current year using the system clock and default time-zone, not null 134 */ 135 public static Year now() { 136 return now(Clock.systemDefaultZone()); 137 } 138 139 /** 140 * Obtains the current year from the system clock in the specified time-zone. 141 * <p> 142 * This will query the {@link Clock#system(ZoneId) system clock} to obtain the current year. 143 * Specifying the time-zone avoids dependence on the default time-zone. 144 * <p> 145 * Using this method will prevent the ability to use an alternate clock for testing 146 * because the clock is hard-coded. 147 * 148 * @param zone the zone ID to use, not null 149 * @return the current year using the system clock, not null 150 */ 151 public static Year now(ZoneId zone) { 152 return now(Clock.system(zone)); 153 } 154 155 /** 156 * Obtains the current year from the specified clock. 157 * <p> 158 * This will query the specified clock to obtain the current year. 159 * Using this method allows the use of an alternate clock for testing. 160 * The alternate clock may be introduced using {@link Clock dependency injection}. 161 * 162 * @param clock the clock to use, not null 163 * @return the current year, not null 164 */ 165 public static Year now(Clock clock) { 166 final LocalDate now = LocalDate.now(clock); // called once 167 return Year.of(now.getYear()); 168 } 169 170 //----------------------------------------------------------------------- 171 /** 172 * Obtains an instance of {@code Year}. 173 * <p> 174 * This method accepts a year value from the proleptic ISO calendar system. 175 * <p> 176 * The year 2AD/CE is represented by 2.<br> 177 * The year 1AD/CE is represented by 1.<br> 178 * The year 1BC/BCE is represented by 0.<br> 179 * The year 2BC/BCE is represented by -1.<br> 180 * 181 * @param isoYear the ISO proleptic year to represent, from {@code MIN_VALUE} to {@code MAX_VALUE} 182 * @return the year, not null 183 * @throws DateTimeException if the field is invalid 184 */ 185 public static Year of(int isoYear) { 186 YEAR.checkValidValue(isoYear); 187 return new Year(isoYear); 188 } 189 190 //----------------------------------------------------------------------- 191 /** 192 * Obtains an instance of {@code Year} from a temporal object. 193 * <p> 194 * A {@code TemporalAccessor} represents some form of date and time information. 195 * This factory converts the arbitrary temporal object to an instance of {@code Year}. 196 * <p> 197 * The conversion extracts the {@link ChronoField#YEAR year} field. 198 * The extraction is only permitted if the temporal object has an ISO 199 * chronology, or can be converted to a {@code LocalDate}. 200 * <p> 201 * This method matches the signature of the functional interface {@link TemporalQuery} 202 * allowing it to be used in queries via method reference, {@code Year::from}. 203 * 204 * @param temporal the temporal object to convert, not null 205 * @return the year, not null 206 * @throws DateTimeException if unable to convert to a {@code Year} 207 */ 208 public static Year from(TemporalAccessor temporal) { 209 if (temporal instanceof Year) { 210 return (Year) temporal; 211 } 212 try { 213 if (ISOChrono.INSTANCE.equals(Chrono.from(temporal)) == false) { 214 temporal = LocalDate.from(temporal); 215 } 216 return of(temporal.get(YEAR)); 217 } catch (DateTimeException ex) { 218 throw new DateTimeException("Unable to obtain Year from TemporalAccessor: " + temporal.getClass(), ex); 219 } 220 } 221 222 //----------------------------------------------------------------------- 223 /** 224 * Obtains an instance of {@code Year} from a text string such as {@code 2007}. 225 * <p> 226 * The string must represent a valid year. 227 * Years outside the range 0000 to 9999 must be prefixed by the plus or minus symbol. 228 * 229 * @param text the text to parse such as "2007", not null 230 * @return the parsed year, not null 231 * @throws DateTimeParseException if the text cannot be parsed 232 */ 233 public static Year parse(CharSequence text) { 234 return parse(text, PARSER); 235 } 236 237 /** 238 * Obtains an instance of {@code Year} from a text string using a specific formatter. 239 * <p> 240 * The text is parsed using the formatter, returning a year. 241 * 242 * @param text the text to parse, not null 243 * @param formatter the formatter to use, not null 244 * @return the parsed year, not null 245 * @throws DateTimeParseException if the text cannot be parsed 246 */ 247 public static Year parse(CharSequence text, DateTimeFormatter formatter) { 248 Objects.requireNonNull(formatter, "formatter"); 249 return formatter.parse(text, Year.class); 250 } 251 252 //------------------------------------------------------------------------- 253 /** 254 * Checks if the year is a leap year, according to the ISO proleptic 255 * calendar system rules. 256 * <p> 257 * This method applies the current rules for leap years across the whole time-line. 258 * In general, a year is a leap year if it is divisible by four without 259 * remainder. However, years divisible by 100, are not leap years, with 260 * the exception of years divisible by 400 which are. 261 * <p> 262 * For example, 1904 is a leap year it is divisible by 4. 263 * 1900 was not a leap year as it is divisible by 100, however 2000 was a 264 * leap year as it is divisible by 400. 265 * <p> 266 * The calculation is proleptic - applying the same rules into the far future and far past. 267 * This is historically inaccurate, but is correct for the ISO-8601 standard. 268 * 269 * @param year the year to check 270 * @return true if the year is leap, false otherwise 271 */ 272 public static boolean isLeap(long year) { 273 return ((year & 3) == 0) && ((year % 100) != 0 || (year % 400) == 0); 274 } 275 276 //----------------------------------------------------------------------- 277 /** 278 * Constructor. 279 * 280 * @param year the year to represent 281 */ 282 private Year(int year) { 283 this.year = year; 284 } 285 286 //----------------------------------------------------------------------- 287 /** 288 * Gets the year value. 289 * <p> 290 * The year returned by this method is proleptic as per {@code get(YEAR)}. 291 * 292 * @return the year, {@code MIN_VALUE} to {@code MAX_VALUE} 293 */ 294 public int getValue() { 295 return year; 296 } 297 298 //----------------------------------------------------------------------- 299 /** 300 * Checks if the specified field is supported. 301 * <p> 302 * This checks if this year can be queried for the specified field. 303 * If false, then calling the {@link #range(TemporalField) range} and 304 * {@link #get(TemporalField) get} methods will throw an exception. 305 * <p> 306 * If the field is a {@link ChronoField} then the query is implemented here. 307 * The {@link #isSupported(TemporalField) supported fields} will return valid 308 * values based on this date-time. 309 * The supported fields are: 310 * <ul> 311 * <li>{@code YEAR_OF_ERA} 312 * <li>{@code YEAR} 313 * <li>{@code ERA} 314 * </ul> 315 * All other {@code ChronoField} instances will return false. 316 * <p> 317 * If the field is not a {@code ChronoField}, then the result of this method 318 * is obtained by invoking {@code TemporalField.doIsSupported(TemporalAccessor)} 319 * passing {@code this} as the argument. 320 * Whether the field is supported is determined by the field. 321 * 322 * @param field the field to check, null returns false 323 * @return true if the field is supported on this year, false if not 324 */ 325 @Override 326 public boolean isSupported(TemporalField field) { 327 if (field instanceof ChronoField) { 328 return field == YEAR || field == YEAR_OF_ERA || field == ERA; 329 } 330 return field != null && field.doIsSupported(this); 331 } 332 333 /** 334 * Gets the range of valid values for the specified field. 335 * <p> 336 * The range object expresses the minimum and maximum valid values for a field. 337 * This year is used to enhance the accuracy of the returned range. 338 * If it is not possible to return the range, because the field is not supported 339 * or for some other reason, an exception is thrown. 340 * <p> 341 * If the field is a {@link ChronoField} then the query is implemented here. 342 * The {@link #isSupported(TemporalField) supported fields} will return 343 * appropriate range instances. 344 * All other {@code ChronoField} instances will throw a {@code DateTimeException}. 345 * <p> 346 * If the field is not a {@code ChronoField}, then the result of this method 347 * is obtained by invoking {@code TemporalField.doRange(TemporalAccessor)} 348 * passing {@code this} as the argument. 349 * Whether the range can be obtained is determined by the field. 350 * 351 * @param field the field to query the range for, not null 352 * @return the range of valid values for the field, not null 353 * @throws DateTimeException if the range for the field cannot be obtained 354 */ 355 @Override 356 public ValueRange range(TemporalField field) { 357 if (field == YEAR_OF_ERA) { 358 return (year <= 0 ? ValueRange.of(1, MAX_VALUE + 1) : ValueRange.of(1, MAX_VALUE)); 359 } 360 return super.range(field); 361 } 362 363 /** 364 * Gets the value of the specified field from this year as an {@code int}. 365 * <p> 366 * This queries this year for the value for the specified field. 367 * The returned value will always be within the valid range of values for the field. 368 * If it is not possible to return the value, because the field is not supported 369 * or for some other reason, an exception is thrown. 370 * <p> 371 * If the field is a {@link ChronoField} then the query is implemented here. 372 * The {@link #isSupported(TemporalField) supported fields} will return valid 373 * values based on this year. 374 * All other {@code ChronoField} instances will throw a {@code DateTimeException}. 375 * <p> 376 * If the field is not a {@code ChronoField}, then the result of this method 377 * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)} 378 * passing {@code this} as the argument. Whether the value can be obtained, 379 * and what the value represents, is determined by the field. 380 * 381 * @param field the field to get, not null 382 * @return the value for the field 383 * @throws DateTimeException if a value for the field cannot be obtained 384 * @throws ArithmeticException if numeric overflow occurs 385 */ 386 @Override // override for Javadoc 387 public int get(TemporalField field) { 388 return range(field).checkValidIntValue(getLong(field), field); 389 } 390 391 /** 392 * Gets the value of the specified field from this year as a {@code long}. 393 * <p> 394 * This queries this year for the value for the specified field. 395 * If it is not possible to return the value, because the field is not supported 396 * or for some other reason, an exception is thrown. 397 * <p> 398 * If the field is a {@link ChronoField} then the query is implemented here. 399 * The {@link #isSupported(TemporalField) supported fields} will return valid 400 * values based on this year. 401 * All other {@code ChronoField} instances will throw a {@code DateTimeException}. 402 * <p> 403 * If the field is not a {@code ChronoField}, then the result of this method 404 * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)} 405 * passing {@code this} as the argument. Whether the value can be obtained, 406 * and what the value represents, is determined by the field. 407 * 408 * @param field the field to get, not null 409 * @return the value for the field 410 * @throws DateTimeException if a value for the field cannot be obtained 411 * @throws ArithmeticException if numeric overflow occurs 412 */ 413 @Override 414 public long getLong(TemporalField field) { 415 if (field instanceof ChronoField) { 416 switch ((ChronoField) field) { 417 case YEAR_OF_ERA: return (year < 1 ? 1 - year : year); 418 case YEAR: return year; 419 case ERA: return (year < 1 ? 0 : 1); 420 } 421 throw new DateTimeException("Unsupported field: " + field.getName()); 422 } 423 return field.doGet(this); 424 } 425 426 //----------------------------------------------------------------------- 427 /** 428 * Checks if the year is a leap year, according to the ISO proleptic 429 * calendar system rules. 430 * <p> 431 * This method applies the current rules for leap years across the whole time-line. 432 * In general, a year is a leap year if it is divisible by four without 433 * remainder. However, years divisible by 100, are not leap years, with 434 * the exception of years divisible by 400 which are. 435 * <p> 436 * For example, 1904 is a leap year it is divisible by 4. 437 * 1900 was not a leap year as it is divisible by 100, however 2000 was a 438 * leap year as it is divisible by 400. 439 * <p> 440 * The calculation is proleptic - applying the same rules into the far future and far past. 441 * This is historically inaccurate, but is correct for the ISO-8601 standard. 442 * 443 * @return true if the year is leap, false otherwise 444 */ 445 public boolean isLeap() { 446 return Year.isLeap(year); 447 } 448 449 /** 450 * Checks if the month-day is valid for this year. 451 * <p> 452 * This method checks whether this year and the input month and day form 453 * a valid date. 454 * 455 * @param monthDay the month-day to validate, null returns false 456 * @return true if the month and day are valid for this year 457 */ 458 public boolean isValidMonthDay(MonthDay monthDay) { 459 return monthDay != null && monthDay.isValidYear(year); 460 } 461 462 /** 463 * Gets the length of this year in days. 464 * 465 * @return the length of this year in days, 365 or 366 466 */ 467 public int length() { 468 return isLeap() ? 366 : 365; 469 } 470 471 //----------------------------------------------------------------------- 472 /** 473 * Returns an adjusted copy of this year. 474 * <p> 475 * This returns a new {@code Year}, based on this one, with the year adjusted. 476 * The adjustment takes place using the specified adjuster strategy object. 477 * Read the documentation of the adjuster to understand what adjustment will be made. 478 * <p> 479 * The result of this method is obtained by invoking the 480 * {@link TemporalAdjuster#adjustInto(Temporal)} method on the 481 * specified adjuster passing {@code this} as the argument. 482 * <p> 483 * This instance is immutable and unaffected by this method call. 484 * 485 * @param adjuster the adjuster to use, not null 486 * @return a {@code Year} based on {@code this} with the adjustment made, not null 487 * @throws DateTimeException if the adjustment cannot be made 488 * @throws ArithmeticException if numeric overflow occurs 489 */ 490 @Override 491 public Year with(TemporalAdjuster adjuster) { 492 return (Year) adjuster.adjustInto(this); 493 } 494 495 /** 496 * Returns a copy of this year with the specified field set to a new value. 497 * <p> 498 * This returns a new {@code Year}, based on this one, with the value 499 * for the specified field changed. 500 * If it is not possible to set the value, because the field is not supported or for 501 * some other reason, an exception is thrown. 502 * <p> 503 * If the field is a {@link ChronoField} then the adjustment is implemented here. 504 * The supported fields behave as follows: 505 * <ul> 506 * <li>{@code YEAR_OF_ERA} - 507 * Returns a {@code Year} with the specified year-of-era 508 * The era will be unchanged. 509 * <li>{@code YEAR} - 510 * Returns a {@code Year} with the specified year. 511 * This completely replaces the date and is equivalent to {@link #of(int)}. 512 * <li>{@code ERA} - 513 * Returns a {@code Year} with the specified era. 514 * The year-of-era will be unchanged. 515 * </ul> 516 * <p> 517 * In all cases, if the new value is outside the valid range of values for the field 518 * then a {@code DateTimeException} will be thrown. 519 * <p> 520 * All other {@code ChronoField} instances will throw a {@code DateTimeException}. 521 * <p> 522 * If the field is not a {@code ChronoField}, then the result of this method 523 * is obtained by invoking {@code TemporalField.doWith(Temporal, long)} 524 * passing {@code this} as the argument. In this case, the field determines 525 * whether and how to adjust the instant. 526 * <p> 527 * This instance is immutable and unaffected by this method call. 528 * 529 * @param field the field to set in the result, not null 530 * @param newValue the new value of the field in the result 531 * @return a {@code Year} based on {@code this} with the specified field set, not null 532 * @throws DateTimeException if the field cannot be set 533 * @throws ArithmeticException if numeric overflow occurs 534 */ 535 @Override 536 public Year with(TemporalField field, long newValue) { 537 if (field instanceof ChronoField) { 538 ChronoField f = (ChronoField) field; 539 f.checkValidValue(newValue); 540 switch (f) { 541 case YEAR_OF_ERA: return Year.of((int) (year < 1 ? 1 - newValue : newValue)); 542 case YEAR: return Year.of((int) newValue); 543 case ERA: return (getLong(ERA) == newValue ? this : Year.of(1 - year)); 544 } 545 throw new DateTimeException("Unsupported field: " + field.getName()); 546 } 547 return field.doWith(this, newValue); 548 } 549 550 //----------------------------------------------------------------------- 551 /** 552 * Returns a copy of this year with the specified period added. 553 * <p> 554 * This method returns a new year based on this year with the specified period added. 555 * The adder is typically {@link Period} but may be any other type implementing 556 * the {@link TemporalAdder} interface. 557 * The calculation is delegated to the specified adjuster, which typically calls 558 * back to {@link #plus(long, TemporalUnit)}. 559 * <p> 560 * This instance is immutable and unaffected by this method call. 561 * 562 * @param adder the adder to use, not null 563 * @return a {@code Year} based on this year with the addition made, not null 564 * @throws DateTimeException if the addition cannot be made 565 * @throws ArithmeticException if numeric overflow occurs 566 */ 567 @Override 568 public Year plus(TemporalAdder adder) { 569 return (Year) adder.addTo(this); 570 } 571 572 /** 573 * {@inheritDoc} 574 * @throws DateTimeException {@inheritDoc} 575 * @throws ArithmeticException {@inheritDoc} 576 */ 577 @Override 578 public Year plus(long amountToAdd, TemporalUnit unit) { 579 if (unit instanceof ChronoUnit) { 580 switch ((ChronoUnit) unit) { 581 case YEARS: return plusYears(amountToAdd); 582 case DECADES: return plusYears(Jdk8Methods.safeMultiply(amountToAdd, 10)); 583 case CENTURIES: return plusYears(Jdk8Methods.safeMultiply(amountToAdd, 100)); 584 case MILLENNIA: return plusYears(Jdk8Methods.safeMultiply(amountToAdd, 1000)); 585 case ERAS: return with(ERA, Jdk8Methods.safeAdd(getLong(ERA), amountToAdd)); 586 } 587 throw new DateTimeException("Unsupported unit: " + unit.getName()); 588 } 589 return unit.doPlus(this, amountToAdd); 590 } 591 592 /** 593 * Returns a copy of this year with the specified number of years added. 594 * <p> 595 * This instance is immutable and unaffected by this method call. 596 * 597 * @param yearsToAdd the years to add, may be negative 598 * @return a {@code Year} based on this year with the period added, not null 599 * @throws DateTimeException if the result exceeds the supported year range 600 */ 601 public Year plusYears(long yearsToAdd) { 602 if (yearsToAdd == 0) { 603 return this; 604 } 605 return of(YEAR.checkValidIntValue(year + yearsToAdd)); // overflow safe 606 } 607 608 //----------------------------------------------------------------------- 609 /** 610 * Returns a copy of this year with the specified period subtracted. 611 * <p> 612 * This method returns a new year based on this year with the specified period subtracted. 613 * The subtractor is typically {@link Period} but may be any other type implementing 614 * the {@link TemporalSubtractor} interface. 615 * The calculation is delegated to the specified adjuster, which typically calls 616 * back to {@link #minus(long, TemporalUnit)}. 617 * <p> 618 * This instance is immutable and unaffected by this method call. 619 * 620 * @param subtractor the subtractor to use, not null 621 * @return a {@code Year} based on this year with the subtraction made, not null 622 * @throws DateTimeException if the subtraction cannot be made 623 * @throws ArithmeticException if numeric overflow occurs 624 */ 625 @Override 626 public Year minus(TemporalSubtractor subtractor) { 627 return (Year) subtractor.subtractFrom(this); 628 } 629 630 /** 631 * {@inheritDoc} 632 * @throws DateTimeException {@inheritDoc} 633 * @throws ArithmeticException {@inheritDoc} 634 */ 635 @Override 636 public Year minus(long amountToSubtract, TemporalUnit unit) { 637 return (amountToSubtract == Long.MIN_VALUE ? plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit)); 638 } 639 640 /** 641 * Returns a copy of this year with the specified number of years subtracted. 642 * <p> 643 * This instance is immutable and unaffected by this method call. 644 * 645 * @param yearsToSubtract the years to subtract, may be negative 646 * @return a {@code Year} based on this year with the period subtracted, not null 647 * @throws DateTimeException if the result exceeds the supported year range 648 */ 649 public Year minusYears(long yearsToSubtract) { 650 return (yearsToSubtract == Long.MIN_VALUE ? plusYears(Long.MAX_VALUE).plusYears(1) : plusYears(-yearsToSubtract)); 651 } 652 653 //----------------------------------------------------------------------- 654 /** 655 * Queries this year using the specified query. 656 * <p> 657 * This queries this year using the specified query strategy object. 658 * The {@code TemporalQuery} object defines the logic to be used to 659 * obtain the result. Read the documentation of the query to understand 660 * what the result of this method will be. 661 * <p> 662 * The result of this method is obtained by invoking the 663 * {@link TemporalQuery#queryFrom(TemporalAccessor)} method on the 664 * specified query passing {@code this} as the argument. 665 * 666 * @param <R> the type of the result 667 * @param query the query to invoke, not null 668 * @return the query result, null may be returned (defined by the query) 669 * @throws DateTimeException if unable to query (defined by the query) 670 * @throws ArithmeticException if numeric overflow occurs (defined by the query) 671 */ 672 @SuppressWarnings("unchecked") 673 @Override 674 public <R> R query(TemporalQuery<R> query) { 675 if (query == TemporalQueries.chrono()) { 676 return (R) ISOChrono.INSTANCE; 677 } else if (query == TemporalQueries.precision()) { 678 return (R) YEARS; 679 } 680 return super.query(query); 681 } 682 683 /** 684 * Adjusts the specified temporal object to have this year. 685 * <p> 686 * This returns a temporal object of the same observable type as the input 687 * with the year changed to be the same as this. 688 * <p> 689 * The adjustment is equivalent to using {@link Temporal#with(TemporalField, long)} 690 * passing {@link ChronoField#YEAR} as the field. 691 * If the specified temporal object does not use the ISO calendar system then 692 * a {@code DateTimeException} is thrown. 693 * <p> 694 * In most cases, it is clearer to reverse the calling pattern by using 695 * {@link Temporal#with(TemporalAdjuster)}: 696 * <pre> 697 * // these two lines are equivalent, but the second approach is recommended 698 * temporal = thisYear.adjustInto(temporal); 699 * temporal = temporal.with(thisYear); 700 * </pre> 701 * <p> 702 * This instance is immutable and unaffected by this method call. 703 * 704 * @param temporal the target object to be adjusted, not null 705 * @return the adjusted object, not null 706 * @throws DateTimeException if unable to make the adjustment 707 * @throws ArithmeticException if numeric overflow occurs 708 */ 709 @Override 710 public Temporal adjustInto(Temporal temporal) { 711 if (Chrono.from(temporal).equals(ISOChrono.INSTANCE) == false) { 712 throw new DateTimeException("Adjustment only supported on ISO date-time"); 713 } 714 return temporal.with(YEAR, year); 715 } 716 717 /** 718 * Calculates the period between this year and another year in 719 * terms of the specified unit. 720 * <p> 721 * This calculates the period between two years in terms of a single unit. 722 * The start and end points are {@code this} and the specified year. 723 * The result will be negative if the end is before the start. 724 * The {@code Temporal} passed to this method must be a {@code Year}. 725 * For example, the period in decades between two year can be calculated 726 * using {@code startYear.periodUntil(endYear, DECADES)}. 727 * <p> 728 * The calculation returns a whole number, representing the number of 729 * complete units between the two years. 730 * For example, the period in decades between 2012 and 2031 731 * will only be one decade as it is one year short of two decades. 732 * <p> 733 * This method operates in association with {@link TemporalUnit#between}. 734 * The result of this method is a {@code long} representing the amount of 735 * the specified unit. By contrast, the result of {@code between} is an 736 * object that can be used directly in addition/subtraction: 737 * <pre> 738 * long period = start.periodUntil(end, YEARS); // this method 739 * dateTime.plus(YEARS.between(start, end)); // use in plus/minus 740 * </pre> 741 * <p> 742 * The calculation is implemented in this method for {@link ChronoUnit}. 743 * The units {@code YEARS}, {@code DECADES}, {@code CENTURIES}, 744 * {@code MILLENNIA} and {@code ERAS} are supported. 745 * Other {@code ChronoUnit} values will throw an exception. 746 * <p> 747 * If the unit is not a {@code ChronoUnit}, then the result of this method 748 * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)} 749 * passing {@code this} as the first argument and the input temporal as 750 * the second argument. 751 * <p> 752 * This instance is immutable and unaffected by this method call. 753 * 754 * @param endYear the end year, which must be a {@code Year}, not null 755 * @param unit the unit to measure the period in, not null 756 * @return the amount of the period between this year and the end year 757 * @throws DateTimeException if the period cannot be calculated 758 * @throws ArithmeticException if numeric overflow occurs 759 */ 760 @Override 761 public long periodUntil(Temporal endYear, TemporalUnit unit) { 762 if (endYear instanceof Year == false) { 763 Objects.requireNonNull(endYear, "endYear"); 764 throw new DateTimeException("Unable to calculate period between objects of two different types"); 765 } 766 Year end = (Year) endYear; 767 if (unit instanceof ChronoUnit) { 768 long yearsUntil = ((long) end.year) - year; // no overflow 769 switch ((ChronoUnit) unit) { 770 case YEARS: return yearsUntil; 771 case DECADES: return yearsUntil / 10; 772 case CENTURIES: return yearsUntil / 100; 773 case MILLENNIA: return yearsUntil / 1000; 774 case ERAS: return end.getLong(ERA) - getLong(ERA); 775 } 776 throw new DateTimeException("Unsupported unit: " + unit.getName()); 777 } 778 return unit.between(this, endYear).getAmount(); 779 } 780 781 //----------------------------------------------------------------------- 782 /** 783 * Returns a date formed from this year at the specified day-of-year. 784 * <p> 785 * This combines this year and the specified day-of-year to form a {@code LocalDate}. 786 * The day-of-year value 366 is only valid in a leap year. 787 * <p> 788 * This instance is immutable and unaffected by this method call. 789 * 790 * @param dayOfYear the day-of-year to use, not null 791 * @return the local date formed from this year and the specified date of year, not null 792 * @throws DateTimeException if the day of year is 366 and this is not a leap year 793 */ 794 public LocalDate atDay(int dayOfYear) { 795 return LocalDate.ofYearDay(year, dayOfYear); 796 } 797 798 /** 799 * Returns a year-month formed from this year at the specified month. 800 * <p> 801 * This combines this year and the specified month to form a {@code YearMonth}. 802 * All possible combinations of year and month are valid. 803 * <p> 804 * This method can be used as part of a chain to produce a date: 805 * <pre> 806 * LocalDate date = year.atMonth(month).atDay(day); 807 * </pre> 808 * <p> 809 * This instance is immutable and unaffected by this method call. 810 * 811 * @param month the month-of-year to use, not null 812 * @return the year-month formed from this year and the specified month, not null 813 */ 814 public YearMonth atMonth(Month month) { 815 return YearMonth.of(year, month); 816 } 817 818 /** 819 * Returns a year-month formed from this year at the specified month. 820 * <p> 821 * This combines this year and the specified month to form a {@code YearMonth}. 822 * All possible combinations of year and month are valid. 823 * <p> 824 * This method can be used as part of a chain to produce a date: 825 * <pre> 826 * LocalDate date = year.atMonth(month).atDay(day); 827 * </pre> 828 * <p> 829 * This instance is immutable and unaffected by this method call. 830 * 831 * @param month the month-of-year to use, from 1 (January) to 12 (December) 832 * @return the year-month formed from this year and the specified month, not null 833 */ 834 public YearMonth atMonth(int month) { 835 return YearMonth.of(year, month); 836 } 837 838 /** 839 * Returns a date formed from this year at the specified month-day. 840 * <p> 841 * This combines this year and the specified month-day to form a {@code LocalDate}. 842 * The month-day value of February 29th is only valid in a leap year. 843 * <p> 844 * This instance is immutable and unaffected by this method call. 845 * 846 * @param monthDay the month-day to use, not null 847 * @return the local date formed from this year and the specified month-day, not null 848 * @throws DateTimeException if the month-day is February 29th and this is not a leap year 849 */ 850 public LocalDate atMonthDay(MonthDay monthDay) { 851 return LocalDate.of(year, monthDay.getMonth(), monthDay.getDayOfMonth()); 852 } 853 854 //----------------------------------------------------------------------- 855 /** 856 * Compares this year to another year. 857 * <p> 858 * The comparison is based on the value of the year. 859 * It is "consistent with equals", as defined by {@link Comparable}. 860 * 861 * @param other the other year to compare to, not null 862 * @return the comparator value, negative if less, positive if greater 863 */ 864 public int compareTo(Year other) { 865 return year - other.year; 866 } 867 868 /** 869 * Is this year after the specified year. 870 * 871 * @param other the other year to compare to, not null 872 * @return true if this is after the specified year 873 */ 874 public boolean isAfter(Year other) { 875 return year > other.year; 876 } 877 878 /** 879 * Is this year before the specified year. 880 * 881 * @param other the other year to compare to, not null 882 * @return true if this point is before the specified year 883 */ 884 public boolean isBefore(Year other) { 885 return year < other.year; 886 } 887 888 //----------------------------------------------------------------------- 889 /** 890 * Checks if this year is equal to another year. 891 * <p> 892 * The comparison is based on the time-line position of the years. 893 * 894 * @param obj the object to check, null returns false 895 * @return true if this is equal to the other year 896 */ 897 @Override 898 public boolean equals(Object obj) { 899 if (this == obj) { 900 return true; 901 } 902 if (obj instanceof Year) { 903 return year == ((Year) obj).year; 904 } 905 return false; 906 } 907 908 /** 909 * A hash code for this year. 910 * 911 * @return a suitable hash code 912 */ 913 @Override 914 public int hashCode() { 915 return year; 916 } 917 918 //----------------------------------------------------------------------- 919 /** 920 * Outputs this year as a {@code String}. 921 * 922 * @return a string representation of this year, not null 923 */ 924 @Override 925 public String toString() { 926 return Integer.toString(year); 927 } 928 929 /** 930 * Outputs this year as a {@code String} using the formatter. 931 * <p> 932 * This year will be passed to the formatter 933 * {@link DateTimeFormatter#print(TemporalAccessor) print method}. 934 * 935 * @param formatter the formatter to use, not null 936 * @return the formatted year string, not null 937 * @throws DateTimeException if an error occurs during printing 938 */ 939 public String toString(DateTimeFormatter formatter) { 940 Objects.requireNonNull(formatter, "formatter"); 941 return formatter.print(this); 942 } 943 944 //----------------------------------------------------------------------- 945 private Object writeReplace() { 946 return new Ser(Ser.YEAR_TYPE, this); 947 } 948 949 /** 950 * Defend against malicious streams. 951 * @return never 952 * @throws InvalidObjectException always 953 */ 954 private Object readResolve() throws ObjectStreamException { 955 throw new InvalidObjectException("Deserialization via serialization delegate"); 956 } 957 958 void writeExternal(DataOutput out) throws IOException { 959 out.writeInt(year); 960 } 961 962 static Year readExternal(DataInput in) throws IOException { 963 return Year.of(in.readInt()); 964 } 965 966}