Home | History | Annotate | Download | only in time
      1 /*
      2  * Copyright (c) 2012, 2015, 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.  Oracle designates this
      8  * particular file as subject to the "Classpath" exception as provided
      9  * by Oracle in the LICENSE file that accompanied this code.
     10  *
     11  * This code is distributed in the hope that it will be useful, but WITHOUT
     12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     14  * version 2 for more details (a copy is included in the LICENSE file that
     15  * accompanied this code).
     16  *
     17  * You should have received a copy of the GNU General Public License version
     18  * 2 along with this work; if not, write to the Free Software Foundation,
     19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     20  *
     21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     22  * or visit www.oracle.com if you need additional information or have any
     23  * questions.
     24  */
     25 
     26 /*
     27  * This file is available under and governed by the GNU General Public
     28  * License version 2 only, as published by the Free Software Foundation.
     29  * However, the following notice accompanied the original version of this
     30  * file:
     31  *
     32  * Copyright (c) 2007-2012, Stephen Colebourne & Michael Nascimento Santos
     33  *
     34  * All rights reserved.
     35  *
     36  * Redistribution and use in source and binary forms, with or without
     37  * modification, are permitted provided that the following conditions are met:
     38  *
     39  *  * Redistributions of source code must retain the above copyright notice,
     40  *    this list of conditions and the following disclaimer.
     41  *
     42  *  * Redistributions in binary form must reproduce the above copyright notice,
     43  *    this list of conditions and the following disclaimer in the documentation
     44  *    and/or other materials provided with the distribution.
     45  *
     46  *  * Neither the name of JSR-310 nor the names of its contributors
     47  *    may be used to endorse or promote products derived from this software
     48  *    without specific prior written permission.
     49  *
     50  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     51  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     52  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     53  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     54  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     55  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     56  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     57  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     58  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     59  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     60  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     61  */
     62 package java.time;
     63 
     64 import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
     65 import static java.time.temporal.ChronoUnit.MONTHS;
     66 
     67 import java.time.chrono.Chronology;
     68 import java.time.chrono.IsoChronology;
     69 import java.time.format.DateTimeFormatterBuilder;
     70 import java.time.format.TextStyle;
     71 import java.time.temporal.ChronoField;
     72 import java.time.temporal.Temporal;
     73 import java.time.temporal.TemporalAccessor;
     74 import java.time.temporal.TemporalAdjuster;
     75 import java.time.temporal.TemporalField;
     76 import java.time.temporal.TemporalQueries;
     77 import java.time.temporal.TemporalQuery;
     78 import java.time.temporal.UnsupportedTemporalTypeException;
     79 import java.time.temporal.ValueRange;
     80 import java.util.Locale;
     81 
     82 /**
     83  * A month-of-year, such as 'July'.
     84  * <p>
     85  * {@code Month} is an enum representing the 12 months of the year -
     86  * January, February, March, April, May, June, July, August, September, October,
     87  * November and December.
     88  * <p>
     89  * In addition to the textual enum name, each month-of-year has an {@code int} value.
     90  * The {@code int} value follows normal usage and the ISO-8601 standard,
     91  * from 1 (January) to 12 (December). It is recommended that applications use the enum
     92  * rather than the {@code int} value to ensure code clarity.
     93  * <p>
     94  * <b>Do not use {@code ordinal()} to obtain the numeric representation of {@code Month}.
     95  * Use {@code getValue()} instead.</b>
     96  * <p>
     97  * This enum represents a common concept that is found in many calendar systems.
     98  * As such, this enum may be used by any calendar system that has the month-of-year
     99  * concept defined exactly equivalent to the ISO-8601 calendar system.
    100  *
    101  * @implSpec
    102  * This is an immutable and thread-safe enum.
    103  *
    104  * @since 1.8
    105  */
    106 public enum Month implements TemporalAccessor, TemporalAdjuster {
    107 
    108     /**
    109      * The singleton instance for the month of January with 31 days.
    110      * This has the numeric value of {@code 1}.
    111      */
    112     JANUARY,
    113     /**
    114      * The singleton instance for the month of February with 28 days, or 29 in a leap year.
    115      * This has the numeric value of {@code 2}.
    116      */
    117     FEBRUARY,
    118     /**
    119      * The singleton instance for the month of March with 31 days.
    120      * This has the numeric value of {@code 3}.
    121      */
    122     MARCH,
    123     /**
    124      * The singleton instance for the month of April with 30 days.
    125      * This has the numeric value of {@code 4}.
    126      */
    127     APRIL,
    128     /**
    129      * The singleton instance for the month of May with 31 days.
    130      * This has the numeric value of {@code 5}.
    131      */
    132     MAY,
    133     /**
    134      * The singleton instance for the month of June with 30 days.
    135      * This has the numeric value of {@code 6}.
    136      */
    137     JUNE,
    138     /**
    139      * The singleton instance for the month of July with 31 days.
    140      * This has the numeric value of {@code 7}.
    141      */
    142     JULY,
    143     /**
    144      * The singleton instance for the month of August with 31 days.
    145      * This has the numeric value of {@code 8}.
    146      */
    147     AUGUST,
    148     /**
    149      * The singleton instance for the month of September with 30 days.
    150      * This has the numeric value of {@code 9}.
    151      */
    152     SEPTEMBER,
    153     /**
    154      * The singleton instance for the month of October with 31 days.
    155      * This has the numeric value of {@code 10}.
    156      */
    157     OCTOBER,
    158     /**
    159      * The singleton instance for the month of November with 30 days.
    160      * This has the numeric value of {@code 11}.
    161      */
    162     NOVEMBER,
    163     /**
    164      * The singleton instance for the month of December with 31 days.
    165      * This has the numeric value of {@code 12}.
    166      */
    167     DECEMBER;
    168     /**
    169      * Private cache of all the constants.
    170      */
    171     private static final Month[] ENUMS = Month.values();
    172 
    173     //-----------------------------------------------------------------------
    174     /**
    175      * Obtains an instance of {@code Month} from an {@code int} value.
    176      * <p>
    177      * {@code Month} is an enum representing the 12 months of the year.
    178      * This factory allows the enum to be obtained from the {@code int} value.
    179      * The {@code int} value follows the ISO-8601 standard, from 1 (January) to 12 (December).
    180      *
    181      * @param month  the month-of-year to represent, from 1 (January) to 12 (December)
    182      * @return the month-of-year, not null
    183      * @throws DateTimeException if the month-of-year is invalid
    184      */
    185     public static Month of(int month) {
    186         if (month < 1 || month > 12) {
    187             throw new DateTimeException("Invalid value for MonthOfYear: " + month);
    188         }
    189         return ENUMS[month - 1];
    190     }
    191 
    192     //-----------------------------------------------------------------------
    193     /**
    194      * Obtains an instance of {@code Month} from a temporal object.
    195      * <p>
    196      * This obtains a month based on the specified temporal.
    197      * A {@code TemporalAccessor} represents an arbitrary set of date and time information,
    198      * which this factory converts to an instance of {@code Month}.
    199      * <p>
    200      * The conversion extracts the {@link ChronoField#MONTH_OF_YEAR MONTH_OF_YEAR} field.
    201      * The extraction is only permitted if the temporal object has an ISO
    202      * chronology, or can be converted to a {@code LocalDate}.
    203      * <p>
    204      * This method matches the signature of the functional interface {@link TemporalQuery}
    205      * allowing it to be used as a query via method reference, {@code Month::from}.
    206      *
    207      * @param temporal  the temporal object to convert, not null
    208      * @return the month-of-year, not null
    209      * @throws DateTimeException if unable to convert to a {@code Month}
    210      */
    211     public static Month from(TemporalAccessor temporal) {
    212         if (temporal instanceof Month) {
    213             return (Month) temporal;
    214         }
    215         try {
    216             if (IsoChronology.INSTANCE.equals(Chronology.from(temporal)) == false) {
    217                 temporal = LocalDate.from(temporal);
    218             }
    219             return of(temporal.get(MONTH_OF_YEAR));
    220         } catch (DateTimeException ex) {
    221             throw new DateTimeException("Unable to obtain Month from TemporalAccessor: " +
    222                     temporal + " of type " + temporal.getClass().getName(), ex);
    223         }
    224     }
    225 
    226     //-----------------------------------------------------------------------
    227     /**
    228      * Gets the month-of-year {@code int} value.
    229      * <p>
    230      * The values are numbered following the ISO-8601 standard,
    231      * from 1 (January) to 12 (December).
    232      *
    233      * @return the month-of-year, from 1 (January) to 12 (December)
    234      */
    235     public int getValue() {
    236         return ordinal() + 1;
    237     }
    238 
    239     //-----------------------------------------------------------------------
    240     /**
    241      * Gets the textual representation, such as 'Jan' or 'December'.
    242      * <p>
    243      * This returns the textual name used to identify the month-of-year,
    244      * suitable for presentation to the user.
    245      * The parameters control the style of the returned text and the locale.
    246      * <p>
    247      * If no textual mapping is found then the {@link #getValue() numeric value} is returned.
    248      *
    249      * @param style  the length of the text required, not null
    250      * @param locale  the locale to use, not null
    251      * @return the text value of the month-of-year, not null
    252      */
    253     public String getDisplayName(TextStyle style, Locale locale) {
    254         return new DateTimeFormatterBuilder().appendText(MONTH_OF_YEAR, style).toFormatter(locale).format(this);
    255     }
    256 
    257     //-----------------------------------------------------------------------
    258     /**
    259      * Checks if the specified field is supported.
    260      * <p>
    261      * This checks if this month-of-year can be queried for the specified field.
    262      * If false, then calling the {@link #range(TemporalField) range} and
    263      * {@link #get(TemporalField) get} methods will throw an exception.
    264      * <p>
    265      * If the field is {@link ChronoField#MONTH_OF_YEAR MONTH_OF_YEAR} then
    266      * this method returns true.
    267      * All other {@code ChronoField} instances will return false.
    268      * <p>
    269      * If the field is not a {@code ChronoField}, then the result of this method
    270      * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)}
    271      * passing {@code this} as the argument.
    272      * Whether the field is supported is determined by the field.
    273      *
    274      * @param field  the field to check, null returns false
    275      * @return true if the field is supported on this month-of-year, false if not
    276      */
    277     @Override
    278     public boolean isSupported(TemporalField field) {
    279         if (field instanceof ChronoField) {
    280             return field == MONTH_OF_YEAR;
    281         }
    282         return field != null && field.isSupportedBy(this);
    283     }
    284 
    285     /**
    286      * Gets the range of valid values for the specified field.
    287      * <p>
    288      * The range object expresses the minimum and maximum valid values for a field.
    289      * This month is used to enhance the accuracy of the returned range.
    290      * If it is not possible to return the range, because the field is not supported
    291      * or for some other reason, an exception is thrown.
    292      * <p>
    293      * If the field is {@link ChronoField#MONTH_OF_YEAR MONTH_OF_YEAR} then the
    294      * range of the month-of-year, from 1 to 12, will be returned.
    295      * All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.
    296      * <p>
    297      * If the field is not a {@code ChronoField}, then the result of this method
    298      * is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessor)}
    299      * passing {@code this} as the argument.
    300      * Whether the range can be obtained is determined by the field.
    301      *
    302      * @param field  the field to query the range for, not null
    303      * @return the range of valid values for the field, not null
    304      * @throws DateTimeException if the range for the field cannot be obtained
    305      * @throws UnsupportedTemporalTypeException if the field is not supported
    306      */
    307     @Override
    308     public ValueRange range(TemporalField field) {
    309         if (field == MONTH_OF_YEAR) {
    310             return field.range();
    311         }
    312         return TemporalAccessor.super.range(field);
    313     }
    314 
    315     /**
    316      * Gets the value of the specified field from this month-of-year as an {@code int}.
    317      * <p>
    318      * This queries this month for the value of the specified field.
    319      * The returned value will always be within the valid range of values for the field.
    320      * If it is not possible to return the value, because the field is not supported
    321      * or for some other reason, an exception is thrown.
    322      * <p>
    323      * If the field is {@link ChronoField#MONTH_OF_YEAR MONTH_OF_YEAR} then the
    324      * value of the month-of-year, from 1 to 12, will be returned.
    325      * All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.
    326      * <p>
    327      * If the field is not a {@code ChronoField}, then the result of this method
    328      * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
    329      * passing {@code this} as the argument. Whether the value can be obtained,
    330      * and what the value represents, is determined by the field.
    331      *
    332      * @param field  the field to get, not null
    333      * @return the value for the field, within the valid range of values
    334      * @throws DateTimeException if a value for the field cannot be obtained or
    335      *         the value is outside the range of valid values for the field
    336      * @throws UnsupportedTemporalTypeException if the field is not supported or
    337      *         the range of values exceeds an {@code int}
    338      * @throws ArithmeticException if numeric overflow occurs
    339      */
    340     @Override
    341     public int get(TemporalField field) {
    342         if (field == MONTH_OF_YEAR) {
    343             return getValue();
    344         }
    345         return TemporalAccessor.super.get(field);
    346     }
    347 
    348     /**
    349      * Gets the value of the specified field from this month-of-year as a {@code long}.
    350      * <p>
    351      * This queries this month for the value of the specified field.
    352      * If it is not possible to return the value, because the field is not supported
    353      * or for some other reason, an exception is thrown.
    354      * <p>
    355      * If the field is {@link ChronoField#MONTH_OF_YEAR MONTH_OF_YEAR} then the
    356      * value of the month-of-year, from 1 to 12, will be returned.
    357      * All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.
    358      * <p>
    359      * If the field is not a {@code ChronoField}, then the result of this method
    360      * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
    361      * passing {@code this} as the argument. Whether the value can be obtained,
    362      * and what the value represents, is determined by the field.
    363      *
    364      * @param field  the field to get, not null
    365      * @return the value for the field
    366      * @throws DateTimeException if a value for the field cannot be obtained
    367      * @throws UnsupportedTemporalTypeException if the field is not supported
    368      * @throws ArithmeticException if numeric overflow occurs
    369      */
    370     @Override
    371     public long getLong(TemporalField field) {
    372         if (field == MONTH_OF_YEAR) {
    373             return getValue();
    374         } else if (field instanceof ChronoField) {
    375             throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
    376         }
    377         return field.getFrom(this);
    378     }
    379 
    380     //-----------------------------------------------------------------------
    381     /**
    382      * Returns the month-of-year that is the specified number of quarters after this one.
    383      * <p>
    384      * The calculation rolls around the end of the year from December to January.
    385      * The specified period may be negative.
    386      * <p>
    387      * This instance is immutable and unaffected by this method call.
    388      *
    389      * @param months  the months to add, positive or negative
    390      * @return the resulting month, not null
    391      */
    392     public Month plus(long months) {
    393         int amount = (int) (months % 12);
    394         return ENUMS[(ordinal() + (amount + 12)) % 12];
    395     }
    396 
    397     /**
    398      * Returns the month-of-year that is the specified number of months before this one.
    399      * <p>
    400      * The calculation rolls around the start of the year from January to December.
    401      * The specified period may be negative.
    402      * <p>
    403      * This instance is immutable and unaffected by this method call.
    404      *
    405      * @param months  the months to subtract, positive or negative
    406      * @return the resulting month, not null
    407      */
    408     public Month minus(long months) {
    409         return plus(-(months % 12));
    410     }
    411 
    412     //-----------------------------------------------------------------------
    413     /**
    414      * Gets the length of this month in days.
    415      * <p>
    416      * This takes a flag to determine whether to return the length for a leap year or not.
    417      * <p>
    418      * February has 28 days in a standard year and 29 days in a leap year.
    419      * April, June, September and November have 30 days.
    420      * All other months have 31 days.
    421      *
    422      * @param leapYear  true if the length is required for a leap year
    423      * @return the length of this month in days, from 28 to 31
    424      */
    425     public int length(boolean leapYear) {
    426         switch (this) {
    427             case FEBRUARY:
    428                 return (leapYear ? 29 : 28);
    429             case APRIL:
    430             case JUNE:
    431             case SEPTEMBER:
    432             case NOVEMBER:
    433                 return 30;
    434             default:
    435                 return 31;
    436         }
    437     }
    438 
    439     /**
    440      * Gets the minimum length of this month in days.
    441      * <p>
    442      * February has a minimum length of 28 days.
    443      * April, June, September and November have 30 days.
    444      * All other months have 31 days.
    445      *
    446      * @return the minimum length of this month in days, from 28 to 31
    447      */
    448     public int minLength() {
    449         switch (this) {
    450             case FEBRUARY:
    451                 return 28;
    452             case APRIL:
    453             case JUNE:
    454             case SEPTEMBER:
    455             case NOVEMBER:
    456                 return 30;
    457             default:
    458                 return 31;
    459         }
    460     }
    461 
    462     /**
    463      * Gets the maximum length of this month in days.
    464      * <p>
    465      * February has a maximum length of 29 days.
    466      * April, June, September and November have 30 days.
    467      * All other months have 31 days.
    468      *
    469      * @return the maximum length of this month in days, from 29 to 31
    470      */
    471     public int maxLength() {
    472         switch (this) {
    473             case FEBRUARY:
    474                 return 29;
    475             case APRIL:
    476             case JUNE:
    477             case SEPTEMBER:
    478             case NOVEMBER:
    479                 return 30;
    480             default:
    481                 return 31;
    482         }
    483     }
    484 
    485     //-----------------------------------------------------------------------
    486     /**
    487      * Gets the day-of-year corresponding to the first day of this month.
    488      * <p>
    489      * This returns the day-of-year that this month begins on, using the leap
    490      * year flag to determine the length of February.
    491      *
    492      * @param leapYear  true if the length is required for a leap year
    493      * @return the day of year corresponding to the first day of this month, from 1 to 336
    494      */
    495     public int firstDayOfYear(boolean leapYear) {
    496         int leap = leapYear ? 1 : 0;
    497         switch (this) {
    498             case JANUARY:
    499                 return 1;
    500             case FEBRUARY:
    501                 return 32;
    502             case MARCH:
    503                 return 60 + leap;
    504             case APRIL:
    505                 return 91 + leap;
    506             case MAY:
    507                 return 121 + leap;
    508             case JUNE:
    509                 return 152 + leap;
    510             case JULY:
    511                 return 182 + leap;
    512             case AUGUST:
    513                 return 213 + leap;
    514             case SEPTEMBER:
    515                 return 244 + leap;
    516             case OCTOBER:
    517                 return 274 + leap;
    518             case NOVEMBER:
    519                 return 305 + leap;
    520             case DECEMBER:
    521             default:
    522                 return 335 + leap;
    523         }
    524     }
    525 
    526     /**
    527      * Gets the month corresponding to the first month of this quarter.
    528      * <p>
    529      * The year can be divided into four quarters.
    530      * This method returns the first month of the quarter for the base month.
    531      * January, February and March return January.
    532      * April, May and June return April.
    533      * July, August and September return July.
    534      * October, November and December return October.
    535      *
    536      * @return the first month of the quarter corresponding to this month, not null
    537      */
    538     public Month firstMonthOfQuarter() {
    539         return ENUMS[(ordinal() / 3) * 3];
    540     }
    541 
    542     //-----------------------------------------------------------------------
    543     /**
    544      * Queries this month-of-year using the specified query.
    545      * <p>
    546      * This queries this month-of-year using the specified query strategy object.
    547      * The {@code TemporalQuery} object defines the logic to be used to
    548      * obtain the result. Read the documentation of the query to understand
    549      * what the result of this method will be.
    550      * <p>
    551      * The result of this method is obtained by invoking the
    552      * {@link TemporalQuery#queryFrom(TemporalAccessor)} method on the
    553      * specified query passing {@code this} as the argument.
    554      *
    555      * @param <R> the type of the result
    556      * @param query  the query to invoke, not null
    557      * @return the query result, null may be returned (defined by the query)
    558      * @throws DateTimeException if unable to query (defined by the query)
    559      * @throws ArithmeticException if numeric overflow occurs (defined by the query)
    560      */
    561     @SuppressWarnings("unchecked")
    562     @Override
    563     public <R> R query(TemporalQuery<R> query) {
    564         if (query == TemporalQueries.chronology()) {
    565             return (R) IsoChronology.INSTANCE;
    566         } else if (query == TemporalQueries.precision()) {
    567             return (R) MONTHS;
    568         }
    569         return TemporalAccessor.super.query(query);
    570     }
    571 
    572     /**
    573      * Adjusts the specified temporal object to have this month-of-year.
    574      * <p>
    575      * This returns a temporal object of the same observable type as the input
    576      * with the month-of-year changed to be the same as this.
    577      * <p>
    578      * The adjustment is equivalent to using {@link Temporal#with(TemporalField, long)}
    579      * passing {@link ChronoField#MONTH_OF_YEAR} as the field.
    580      * If the specified temporal object does not use the ISO calendar system then
    581      * a {@code DateTimeException} is thrown.
    582      * <p>
    583      * In most cases, it is clearer to reverse the calling pattern by using
    584      * {@link Temporal#with(TemporalAdjuster)}:
    585      * <pre>
    586      *   // these two lines are equivalent, but the second approach is recommended
    587      *   temporal = thisMonth.adjustInto(temporal);
    588      *   temporal = temporal.with(thisMonth);
    589      * </pre>
    590      * <p>
    591      * For example, given a date in May, the following are output:
    592      * <pre>
    593      *   dateInMay.with(JANUARY);    // four months earlier
    594      *   dateInMay.with(APRIL);      // one months earlier
    595      *   dateInMay.with(MAY);        // same date
    596      *   dateInMay.with(JUNE);       // one month later
    597      *   dateInMay.with(DECEMBER);   // seven months later
    598      * </pre>
    599      * <p>
    600      * This instance is immutable and unaffected by this method call.
    601      *
    602      * @param temporal  the target object to be adjusted, not null
    603      * @return the adjusted object, not null
    604      * @throws DateTimeException if unable to make the adjustment
    605      * @throws ArithmeticException if numeric overflow occurs
    606      */
    607     @Override
    608     public Temporal adjustInto(Temporal temporal) {
    609         if (Chronology.from(temporal).equals(IsoChronology.INSTANCE) == false) {
    610             throw new DateTimeException("Adjustment only supported on ISO date-time");
    611         }
    612         return temporal.with(MONTH_OF_YEAR, getValue());
    613     }
    614 
    615 }
    616