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.MONTH_OF_YEAR; 035import static org.threeten.bp.temporal.ChronoUnit.MONTHS; 036 037import java.util.Locale; 038 039import org.threeten.bp.format.DateTimeFormatterBuilder; 040import org.threeten.bp.format.TextStyle; 041import org.threeten.bp.temporal.Chrono; 042import org.threeten.bp.temporal.ChronoField; 043import org.threeten.bp.temporal.ISOChrono; 044import org.threeten.bp.temporal.Temporal; 045import org.threeten.bp.temporal.TemporalAccessor; 046import org.threeten.bp.temporal.TemporalAdjuster; 047import org.threeten.bp.temporal.TemporalField; 048import org.threeten.bp.temporal.TemporalQueries; 049import org.threeten.bp.temporal.TemporalQuery; 050import org.threeten.bp.temporal.ValueRange; 051 052/** 053 * A month-of-year, such as 'July'. 054 * <p> 055 * {@code Month} is an enum representing the 12 months of the year - 056 * January, February, March, April, May, June, July, August, September, October, 057 * November and December. 058 * <p> 059 * In addition to the textual enum name, each month-of-year has an {@code int} value. 060 * The {@code int} value follows normal usage and the ISO-8601 standard, 061 * from 1 (January) to 12 (December). It is recommended that applications use the enum 062 * rather than the {@code int} value to ensure code clarity. 063 * <p> 064 * <b>Do not use {@code ordinal()} to obtain the numeric representation of {@code Month}. 065 * Use {@code getValue()} instead.</b> 066 * <p> 067 * This enum represents a common concept that is found in many calendar systems. 068 * As such, this enum may be used by any calendar system that has the month-of-year 069 * concept defined exactly equivalent to the ISO-8601 calendar system. 070 * 071 * <h3>Specification for implementors</h3> 072 * This is an immutable and thread-safe enum. 073 */ 074public enum Month implements TemporalAccessor, TemporalAdjuster { 075 076 /** 077 * The singleton instance for the month of January with 31 days. 078 * This has the numeric value of {@code 1}. 079 */ 080 JANUARY, 081 /** 082 * The singleton instance for the month of February with 28 days, or 29 in a leap year. 083 * This has the numeric value of {@code 2}. 084 */ 085 FEBRUARY, 086 /** 087 * The singleton instance for the month of March with 31 days. 088 * This has the numeric value of {@code 3}. 089 */ 090 MARCH, 091 /** 092 * The singleton instance for the month of April with 30 days. 093 * This has the numeric value of {@code 4}. 094 */ 095 APRIL, 096 /** 097 * The singleton instance for the month of May with 31 days. 098 * This has the numeric value of {@code 5}. 099 */ 100 MAY, 101 /** 102 * The singleton instance for the month of June with 30 days. 103 * This has the numeric value of {@code 6}. 104 */ 105 JUNE, 106 /** 107 * The singleton instance for the month of July with 31 days. 108 * This has the numeric value of {@code 7}. 109 */ 110 JULY, 111 /** 112 * The singleton instance for the month of August with 31 days. 113 * This has the numeric value of {@code 8}. 114 */ 115 AUGUST, 116 /** 117 * The singleton instance for the month of September with 30 days. 118 * This has the numeric value of {@code 9}. 119 */ 120 SEPTEMBER, 121 /** 122 * The singleton instance for the month of October with 31 days. 123 * This has the numeric value of {@code 10}. 124 */ 125 OCTOBER, 126 /** 127 * The singleton instance for the month of November with 30 days. 128 * This has the numeric value of {@code 11}. 129 */ 130 NOVEMBER, 131 /** 132 * The singleton instance for the month of December with 31 days. 133 * This has the numeric value of {@code 12}. 134 */ 135 DECEMBER; 136 /** 137 * Private cache of all the constants. 138 */ 139 private static final Month[] ENUMS = Month.values(); 140 141 //----------------------------------------------------------------------- 142 /** 143 * Obtains an instance of {@code Month} from an {@code int} value. 144 * <p> 145 * {@code Month} is an enum representing the 12 months of the year. 146 * This factory allows the enum to be obtained from the {@code int} value. 147 * The {@code int} value follows the ISO-8601 standard, from 1 (January) to 12 (December). 148 * 149 * @param month the month-of-year to represent, from 1 (January) to 12 (December) 150 * @return the month-of-year, not null 151 * @throws DateTimeException if the month-of-year is invalid 152 */ 153 public static Month of(int month) { 154 if (month < 1 || month > 12) { 155 throw new DateTimeException("Invalid value for MonthOfYear: " + month); 156 } 157 return ENUMS[month - 1]; 158 } 159 160 //----------------------------------------------------------------------- 161 /** 162 * Obtains an instance of {@code Month} from a temporal object. 163 * <p> 164 * A {@code TemporalAccessor} represents some form of date and time information. 165 * This factory converts the arbitrary temporal object to an instance of {@code Month}. 166 * <p> 167 * The conversion extracts the {@link ChronoField#MONTH_OF_YEAR MONTH_OF_YEAR} field. 168 * The extraction is only permitted if the temporal object has an ISO 169 * chronology, or can be converted to a {@code LocalDate}. 170 * <p> 171 * This method matches the signature of the functional interface {@link TemporalQuery} 172 * allowing it to be used in queries via method reference, {@code Month::from}. 173 * 174 * @param temporal the temporal object to convert, not null 175 * @return the month-of-year, not null 176 * @throws DateTimeException if unable to convert to a {@code Month} 177 */ 178 public static Month from(TemporalAccessor temporal) { 179 if (temporal instanceof Month) { 180 return (Month) temporal; 181 } 182 try { 183 if (ISOChrono.INSTANCE.equals(Chrono.from(temporal)) == false) { 184 temporal = LocalDate.from(temporal); 185 } 186 return of(temporal.get(MONTH_OF_YEAR)); 187 } catch (DateTimeException ex) { 188 throw new DateTimeException("Unable to obtain Month from TemporalAccessor: " + temporal.getClass(), ex); 189 } 190 } 191 192 //----------------------------------------------------------------------- 193 /** 194 * Gets the month-of-year {@code int} value. 195 * <p> 196 * The values are numbered following the ISO-8601 standard, 197 * from 1 (January) to 12 (December). 198 * 199 * @return the month-of-year, from 1 (January) to 12 (December) 200 */ 201 public int getValue() { 202 return ordinal() + 1; 203 } 204 205 //----------------------------------------------------------------------- 206 /** 207 * Gets the textual representation, such as 'Jan' or 'December'. 208 * <p> 209 * This returns the textual name used to identify the month-of-year. 210 * The parameters control the length of the returned text and the locale. 211 * <p> 212 * If no textual mapping is found then the {@link #getValue() numeric value} is returned. 213 * 214 * @param style the length of the text required, not null 215 * @param locale the locale to use, not null 216 * @return the text value of the month-of-year, not null 217 */ 218 public String getText(TextStyle style, Locale locale) { 219 return new DateTimeFormatterBuilder().appendText(MONTH_OF_YEAR, style).toFormatter(locale).print(this); 220 } 221 222 //----------------------------------------------------------------------- 223 /** 224 * Checks if the specified field is supported. 225 * <p> 226 * This checks if this month-of-year can be queried for the specified field. 227 * If false, then calling the {@link #range(TemporalField) range} and 228 * {@link #get(TemporalField) get} methods will throw an exception. 229 * <p> 230 * If the field is {@link ChronoField#MONTH_OF_YEAR MONTH_OF_YEAR} then 231 * this method returns true. 232 * All other {@code ChronoField} instances will return false. 233 * <p> 234 * If the field is not a {@code ChronoField}, then the result of this method 235 * is obtained by invoking {@code TemporalField.doIsSupported(TemporalAccessor)} 236 * passing {@code this} as the argument. 237 * Whether the field is supported is determined by the field. 238 * 239 * @param field the field to check, null returns false 240 * @return true if the field is supported on this month-of-year, false if not 241 */ 242 @Override 243 public boolean isSupported(TemporalField field) { 244 if (field instanceof ChronoField) { 245 return field == MONTH_OF_YEAR; 246 } 247 return field != null && field.doIsSupported(this); 248 } 249 250 /** 251 * Gets the range of valid values for the specified field. 252 * <p> 253 * The range object expresses the minimum and maximum valid values for a field. 254 * This month is used to enhance the accuracy of the returned range. 255 * If it is not possible to return the range, because the field is not supported 256 * or for some other reason, an exception is thrown. 257 * <p> 258 * If the field is {@link ChronoField#MONTH_OF_YEAR MONTH_OF_YEAR} then the 259 * range of the month-of-year, from 1 to 12, will be returned. 260 * All other {@code ChronoField} instances will throw a {@code DateTimeException}. 261 * <p> 262 * If the field is not a {@code ChronoField}, then the result of this method 263 * is obtained by invoking {@code TemporalField.doRange(TemporalAccessor)} 264 * passing {@code this} as the argument. 265 * Whether the range can be obtained is determined by the field. 266 * 267 * @param field the field to query the range for, not null 268 * @return the range of valid values for the field, not null 269 * @throws DateTimeException if the range for the field cannot be obtained 270 */ 271 @Override 272 public ValueRange range(TemporalField field) { 273 if (field == MONTH_OF_YEAR) { 274 return field.range(); 275 } else if (field instanceof ChronoField) { 276 throw new DateTimeException("Unsupported field: " + field.getName()); 277 } 278 return field.doRange(this); 279 } 280 281 /** 282 * Gets the value of the specified field from this month-of-year as an {@code int}. 283 * <p> 284 * This queries this month for the value for the specified field. 285 * The returned value will always be within the valid range of values for the field. 286 * If it is not possible to return the value, because the field is not supported 287 * or for some other reason, an exception is thrown. 288 * <p> 289 * If the field is {@link ChronoField#MONTH_OF_YEAR MONTH_OF_YEAR} then the 290 * value of the month-of-year, from 1 to 12, will be returned. 291 * All other {@code ChronoField} instances will throw a {@code DateTimeException}. 292 * <p> 293 * If the field is not a {@code ChronoField}, then the result of this method 294 * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)} 295 * passing {@code this} as the argument. Whether the value can be obtained, 296 * and what the value represents, is determined by the field. 297 * 298 * @param field the field to get, not null 299 * @return the value for the field, within the valid range of values 300 * @throws DateTimeException if a value for the field cannot be obtained 301 * @throws DateTimeException if the range of valid values for the field exceeds an {@code int} 302 * @throws DateTimeException if the value is outside the range of valid values for the field 303 * @throws ArithmeticException if numeric overflow occurs 304 */ 305 @Override 306 public int get(TemporalField field) { 307 if (field == MONTH_OF_YEAR) { 308 return getValue(); 309 } 310 return range(field).checkValidIntValue(getLong(field), field); 311 } 312 313 /** 314 * Gets the value of the specified field from this month-of-year as a {@code long}. 315 * <p> 316 * This queries this month for the value for the specified field. 317 * If it is not possible to return the value, because the field is not supported 318 * or for some other reason, an exception is thrown. 319 * <p> 320 * If the field is {@link ChronoField#MONTH_OF_YEAR MONTH_OF_YEAR} then the 321 * value of the month-of-year, from 1 to 12, will be returned. 322 * All other {@code ChronoField} instances will throw a {@code DateTimeException}. 323 * <p> 324 * If the field is not a {@code ChronoField}, then the result of this method 325 * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)} 326 * passing {@code this} as the argument. Whether the value can be obtained, 327 * and what the value represents, is determined by the field. 328 * 329 * @param field the field to get, not null 330 * @return the value for the field 331 * @throws DateTimeException if a value for the field cannot be obtained 332 * @throws ArithmeticException if numeric overflow occurs 333 */ 334 @Override 335 public long getLong(TemporalField field) { 336 if (field == MONTH_OF_YEAR) { 337 return getValue(); 338 } else if (field instanceof ChronoField) { 339 throw new DateTimeException("Unsupported field: " + field.getName()); 340 } 341 return field.doGet(this); 342 } 343 344 //----------------------------------------------------------------------- 345 /** 346 * Returns the month-of-year that is the specified number of quarters after this one. 347 * <p> 348 * The calculation rolls around the end of the year from December to January. 349 * The specified period may be negative. 350 * <p> 351 * This instance is immutable and unaffected by this method call. 352 * 353 * @param months the months to add, positive or negative 354 * @return the resulting month, not null 355 */ 356 public Month plus(long months) { 357 int amount = (int) (months % 12); 358 return ENUMS[(ordinal() + (amount + 12)) % 12]; 359 } 360 361 /** 362 * Returns the month-of-year that is the specified number of months before this one. 363 * <p> 364 * The calculation rolls around the start of the year from January to December. 365 * The specified period may be negative. 366 * <p> 367 * This instance is immutable and unaffected by this method call. 368 * 369 * @param months the months to subtract, positive or negative 370 * @return the resulting month, not null 371 */ 372 public Month minus(long months) { 373 return plus(-(months % 12)); 374 } 375 376 //----------------------------------------------------------------------- 377 /** 378 * Gets the length of this month in days. 379 * <p> 380 * This takes a flag to determine whether to return the length for a leap year or not. 381 * <p> 382 * February has 28 days in a standard year and 29 days in a leap year. 383 * April, June, September and November have 30 days. 384 * All other months have 31 days. 385 * 386 * @param leapYear true if the length is required for a leap year 387 * @return the length of this month in days, from 28 to 31 388 */ 389 public int length(boolean leapYear) { 390 switch (this) { 391 case FEBRUARY: 392 return (leapYear ? 29 : 28); 393 case APRIL: 394 case JUNE: 395 case SEPTEMBER: 396 case NOVEMBER: 397 return 30; 398 default: 399 return 31; 400 } 401 } 402 403 /** 404 * Gets the minimum length of this month in days. 405 * <p> 406 * February has a minimum length of 28 days. 407 * April, June, September and November have 30 days. 408 * All other months have 31 days. 409 * 410 * @return the minimum length of this month in days, from 28 to 31 411 */ 412 public int minLength() { 413 switch (this) { 414 case FEBRUARY: 415 return 28; 416 case APRIL: 417 case JUNE: 418 case SEPTEMBER: 419 case NOVEMBER: 420 return 30; 421 default: 422 return 31; 423 } 424 } 425 426 /** 427 * Gets the maximum length of this month in days. 428 * <p> 429 * February has a maximum length of 29 days. 430 * April, June, September and November have 30 days. 431 * All other months have 31 days. 432 * 433 * @return the maximum length of this month in days, from 29 to 31 434 */ 435 public int maxLength() { 436 switch (this) { 437 case FEBRUARY: 438 return 29; 439 case APRIL: 440 case JUNE: 441 case SEPTEMBER: 442 case NOVEMBER: 443 return 30; 444 default: 445 return 31; 446 } 447 } 448 449 //----------------------------------------------------------------------- 450 /** 451 * Gets the day-of-year corresponding to the first day of this month. 452 * <p> 453 * This returns the day-of-year that this month begins on, using the leap 454 * year flag to determine the length of February. 455 * 456 * @param leapYear true if the length is required for a leap year 457 * @return the day of year corresponding to the first day of this month, from 1 to 336 458 */ 459 public int firstDayOfYear(boolean leapYear) { 460 int leap = leapYear ? 1 : 0; 461 switch (this) { 462 case JANUARY: 463 return 1; 464 case FEBRUARY: 465 return 32; 466 case MARCH: 467 return 60 + leap; 468 case APRIL: 469 return 91 + leap; 470 case MAY: 471 return 121 + leap; 472 case JUNE: 473 return 152 + leap; 474 case JULY: 475 return 182 + leap; 476 case AUGUST: 477 return 213 + leap; 478 case SEPTEMBER: 479 return 244 + leap; 480 case OCTOBER: 481 return 274 + leap; 482 case NOVEMBER: 483 return 305 + leap; 484 case DECEMBER: 485 default: 486 return 335 + leap; 487 } 488 } 489 490 /** 491 * Gets the month corresponding to the first month of this quarter. 492 * <p> 493 * The year can be divided into four quarters. 494 * This method returns the first month of the quarter for the base month. 495 * January, February and March return January. 496 * April, May and June return April. 497 * July, August and September return July. 498 * October, November and December return October. 499 * 500 * @return the first month of the quarter corresponding to this month, not null 501 */ 502 public Month firstMonthOfQuarter() { 503 return ENUMS[(ordinal() / 3) * 3]; 504 } 505 506 //----------------------------------------------------------------------- 507 /** 508 * Queries this month-of-year using the specified query. 509 * <p> 510 * This queries this month-of-year using the specified query strategy object. 511 * The {@code TemporalQuery} object defines the logic to be used to 512 * obtain the result. Read the documentation of the query to understand 513 * what the result of this method will be. 514 * <p> 515 * The result of this method is obtained by invoking the 516 * {@link TemporalQuery#queryFrom(TemporalAccessor)} method on the 517 * specified query passing {@code this} as the argument. 518 * 519 * @param <R> the type of the result 520 * @param query the query to invoke, not null 521 * @return the query result, null may be returned (defined by the query) 522 * @throws DateTimeException if unable to query (defined by the query) 523 * @throws ArithmeticException if numeric overflow occurs (defined by the query) 524 */ 525 @SuppressWarnings("unchecked") 526 @Override 527 public <R> R query(TemporalQuery<R> query) { 528 if (query == TemporalQueries.chrono()) { 529 return (R) ISOChrono.INSTANCE; 530 } else if (query == TemporalQueries.precision()) { 531 return (R) MONTHS; 532 } else if (query == TemporalQueries.zoneId()) { 533 return null; 534 } 535 return query.queryFrom(this); 536 } 537 538 /** 539 * Adjusts the specified temporal object to have this month-of-year. 540 * <p> 541 * This returns a temporal object of the same observable type as the input 542 * with the month-of-year changed to be the same as this. 543 * <p> 544 * The adjustment is equivalent to using {@link Temporal#with(TemporalField, long)} 545 * passing {@link ChronoField#MONTH_OF_YEAR} as the field. 546 * If the specified temporal object does not use the ISO calendar system then 547 * a {@code DateTimeException} is thrown. 548 * <p> 549 * In most cases, it is clearer to reverse the calling pattern by using 550 * {@link Temporal#with(TemporalAdjuster)}: 551 * <pre> 552 * // these two lines are equivalent, but the second approach is recommended 553 * temporal = thisMonth.adjustInto(temporal); 554 * temporal = temporal.with(thisMonth); 555 * </pre> 556 * <p> 557 * For example, given a date in May, the following are output: 558 * <pre> 559 * dateInMay.with(JANUARY); // four months earlier 560 * dateInMay.with(APRIL); // one months earlier 561 * dateInMay.with(MAY); // same date 562 * dateInMay.with(JUNE); // one month later 563 * dateInMay.with(DECEMBER); // seven months later 564 * </pre> 565 * <p> 566 * This instance is immutable and unaffected by this method call. 567 * 568 * @param temporal the target object to be adjusted, not null 569 * @return the adjusted object, not null 570 * @throws DateTimeException if unable to make the adjustment 571 * @throws ArithmeticException if numeric overflow occurs 572 */ 573 @Override 574 public Temporal adjustInto(Temporal temporal) { 575 if (Chrono.from(temporal).equals(ISOChrono.INSTANCE) == false) { 576 throw new DateTimeException("Adjustment only supported on ISO date-time"); 577 } 578 return temporal.with(MONTH_OF_YEAR, getValue()); 579 } 580 581}