????
Current Path : C:/inetpub/vhost/binhdinhinvest.gdtvietnam.com/api/node_modules/@js-joda/core/src/ |
Current File : C:/inetpub/vhost/binhdinhinvest.gdtvietnam.com/api/node_modules/@js-joda/core/src/Month.js |
/** * @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper * @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos * @license BSD-3-Clause (see LICENSE in the root directory of this source tree) */ import { assert, requireNonNull, requireInstance } from './assert'; import { MathUtil } from './MathUtil'; import { ChronoField } from './temporal/ChronoField'; import { ChronoUnit } from './temporal/ChronoUnit'; import { DateTimeException, IllegalArgumentException, UnsupportedTemporalTypeException } from './errors'; import { IsoChronology } from './chrono/IsoChronology'; import { TemporalAccessor } from './temporal/TemporalAccessor'; import { TemporalQueries } from './temporal/TemporalQueries'; /** * A month-of-year, such as 'July'. * * {@link Month} is representing the 12 months of the year - * January, February, March, April, May, June, July, August, September, October, * November and December. * * In addition to the textual name, each month-of-year has an `int` value. * The `int` value follows normal usage and the ISO-8601 standard, * from 1 (January) to 12 (December). It is recommended that applications use the static values defined by this class * rather than the `int` value to ensure code clarity. * * This class represents a common concept that is found in many calendar systems. * As such, this class may be used by any calendar system that has the month-of-year * concept defined exactly equivalent to the ISO-8601 calendar system. * * ### Static properties of Class {@link Month} * * Month.JANUARY, Month.FEBRUARY, Month.MARCH, Month.APRIL, Month.MAY, Month.JUNE, * Month.JULY, Month.AUGUST, Month.SEPTEMBER, Month.OCTOBER, Month.NOVEMBER, Month.DECEMBER * */ export class Month extends TemporalAccessor { /** * * @param {number} ordinal * @param {string} name * @private */ constructor(value, name){ super(); this._value = MathUtil.safeToInt(value); this._name = name; } /** * * @return {number} gets the value */ value() { return this._value; } /** * * @returns {number} */ ordinal(){ return this._value - 1; } /** * * @returns {string} */ name(){ return this._name; } /** * Gets the textual representation, such as 'Jan' or 'December'. * * This returns the textual name used to identify the month-of-year. * The parameters control the length of the returned text and the locale. * * If no textual mapping is found then the numeric value (see {@link getValue}) is returned. * * @param {TextStyle} style - the length of the text required, not null * @param {Locale} locale - the locale to use, not null * @return {string} the text value of the day-of-week, not null */ // eslint-disable-next-line no-unused-vars displayName(style, locale) { // TODO: throw new IllegalArgumentException('Pattern using (localized) text not implemented yet!'); } /** * Checks if the specified field is supported. * * This checks if this month-of-year can be queried for the specified field. * If false, then calling the range (see {@link range}) and * get (see {@link get}) methods will throw an exception. * * If the field is MONTH_OF_YEAR (see {@link ChronoField#MONTH_OF_YEAR}) then * this method returns true. * All other {@link ChronoField} instances will return false. * * If the field is not a {@link ChronoField}, then the result of this method * is obtained by invoking {@link TemporalField.isSupportedBy} * passing `this` as the argument. * Whether the field is supported is determined by the field. * * @param {TemporalField} field - the field to check, null returns false * @return {boolean} true if the field is supported on this month-of-year, false if not */ isSupported(field) { if (null === field) { return false; } if (field instanceof ChronoField) { return field === ChronoField.MONTH_OF_YEAR; } return field != null && field.isSupportedBy(this); } /** * Gets the value of the specified field from this month-of-year as an `int`. * * This queries this month for the value of the specified field. * The returned value will always be within the valid range of values for the field. * If it is not possible to return the value, because the field is not supported * or for some other reason, an exception is thrown. * * If the field is MONTH_OF_YEAR (see {@link ChronoField#MONTH_OF_YEAR}) then the * value of the month-of-year, from 1 to 12, will be returned. * All other {@link ChronoField} instances will throw an {@link UnsupportedTemporalTypeException}. * * If the field is not a {@link ChronoField}, then the result of this method * is obtained by invoking {@link TemporalField.getFrom} * passing `this` as the argument. Whether the value can be obtained, * and what the value represents, is determined by the field. * * @param {TemporalField} field - the field to get, not null * @return {Number} the value for the field, within the valid range of values * @throws DateTimeException if a value for the field cannot be obtained or * the value is outside the range of valid values for the field * @throws UnsupportedTemporalTypeException if the field is not supported or * the range of values exceeds an `int` * @throws ArithmeticException if numeric overflow occurs */ get(field) { if (field === ChronoField.MONTH_OF_YEAR) { return this.value(); } return this.range(field).checkValidIntValue(this.getLong(field), field); } /** * Gets the value of the specified field from this month-of-year as a `long`. * * This queries this month for the value of the specified field. * If it is not possible to return the value, because the field is not supported * or for some other reason, an exception is thrown. * * If the field is MONTH_OF_YEAR (see {@link ChronoField#MONTH_OF_YEAR}) then the * value of the month-of-year, from 1 to 12, will be returned. * All other {@link ChronoField} instances will throw an {@link UnsupportedTemporalTypeException}. * * If the field is not a {@link ChronoField}, then the result of this method * is obtained by invoking {@link TemporalField.getFrom} * passing `this` as the argument. Whether the value can be obtained, * and what the value represents, is determined by the field. * * @param {TemporalField} field - the field to get, not null * @return {Number} the value for the field * @throws DateTimeException if a value for the field cannot be obtained * @throws UnsupportedTemporalTypeException if the field is not supported * @throws ArithmeticException if numeric overflow occurs */ getLong(field) { if (field === ChronoField.MONTH_OF_YEAR) { return this.value(); } else if (field instanceof ChronoField) { throw new UnsupportedTemporalTypeException(`Unsupported field: ${field}`); } return field.getFrom(this); } /** * Returns the month-of-year that is the specified number of months after this one. * * The calculation rolls around the end of the year from December to January. * The specified period may be negative. * * This instance is immutable and unaffected by this method call. * * @param {number} months - the months to add, positive or negative * @return {Month} the resulting month, not null */ plus(months) { const amount = MathUtil.intMod(months, 12) + 12; // + 12 to make sure negative arguments are positive, the total is "corrected" by the next % 12 let newMonthVal = MathUtil.intMod((this.value() + amount), 12); /* December is 12, not 0, but 12 % 12 = 0 */ newMonthVal = newMonthVal === 0 ? 12 : newMonthVal; return Month.of(newMonthVal); } /** * Returns the month-of-year that is the specified number of months before this one. * * The calculation rolls around the start of the year from January to December. * The specified period may be negative. * * This instance is immutable and unaffected by this method call. * * @param {number} months - the months to subtract, positive or negative * @return {Month} the resulting month, not null */ minus(months) { return this.plus(-1 * MathUtil.intMod(months, 12)); } /** * Gets the length of this month in days. * * This takes a flag to determine whether to return the length for a leap year or not. * * February has 28 days in a standard year and 29 days in a leap year. * April, June, September and November have 30 days. * All other months have 31 days. * * @param {boolean} leapYear - true if the length is required for a leap year * @return {number} the length of this month in days, from 28 to 31 */ length(leapYear) { switch (this) { case Month.FEBRUARY: return (leapYear ? 29 : 28); case Month.APRIL: case Month.JUNE: case Month.SEPTEMBER: case Month.NOVEMBER: return 30; default: return 31; } } /** * Gets the minimum length of this month in days. * * February has a minimum length of 28 days. * April, June, September and November have 30 days. * All other months have 31 days. * * @return {number} the minimum length of this month in days, from 28 to 31 */ minLength() { switch (this) { case Month.FEBRUARY: return 28; case Month.APRIL: case Month.JUNE: case Month.SEPTEMBER: case Month.NOVEMBER: return 30; default: return 31; } } /** * Gets the maximum length of this month in days. * * February has a maximum length of 29 days. * April, June, September and November have 30 days. * All other months have 31 days. * * @return {number} the maximum length of this month in days, from 29 to 31 */ maxLength() { switch (this) { case Month.FEBRUARY: return 29; case Month.APRIL: case Month.JUNE: case Month.SEPTEMBER: case Month.NOVEMBER: return 30; default: return 31; } } /** * Gets the day-of-year corresponding to the first day of this month. * * This returns the day-of-year that this month begins on, using the leap * year flag to determine the length of February. * * @param {boolean} leapYear - true if the length is required for a leap year * @return {number} the day of year corresponding to the first day of this month, from 1 to 336 */ firstDayOfYear(leapYear) { const leap = leapYear ? 1 : 0; switch (this) { case Month.JANUARY: return 1; case Month.FEBRUARY: return 32; case Month.MARCH: return 60 + leap; case Month.APRIL: return 91 + leap; case Month.MAY: return 121 + leap; case Month.JUNE: return 152 + leap; case Month.JULY: return 182 + leap; case Month.AUGUST: return 213 + leap; case Month.SEPTEMBER: return 244 + leap; case Month.OCTOBER: return 274 + leap; case Month.NOVEMBER: return 305 + leap; case Month.DECEMBER: default: return 335 + leap; } } /** * Gets the month corresponding to the first month of this quarter. * * The year can be divided into four quarters. * This method returns the first month of the quarter for the base month. * January, February and March return January. * April, May and June return April. * July, August and September return July. * October, November and December return October. * * @return {Month} the first month of the quarter corresponding to this month, not null */ firstMonthOfQuarter() { switch (this) { case Month.JANUARY: case Month.FEBRUARY: case Month.MARCH: return Month.JANUARY; case Month.APRIL: case Month.MAY: case Month.JUNE: return Month.APRIL; case Month.JULY: case Month.AUGUST: case Month.SEPTEMBER: return Month.JULY; case Month.OCTOBER: case Month.NOVEMBER: case Month.DECEMBER: default: return Month.OCTOBER; } } /** * Queries this month-of-year using the specified query. * * This queries this month-of-year using the specified query strategy object. * The {@link TemporalQuery} object defines the logic to be used to * obtain the result. Read the documentation of the query to understand * what the result of this method will be. * * The result of this method is obtained by invoking the * {@link TemporalQuery#queryFrom} method on the * specified query passing `this` as the argument. * * @param {TemporalQuery} query - the query to invoke, not null * @return {*} the query result, null may be returned (defined by the query) * @throws DateTimeException if unable to query (defined by the query) * @throws ArithmeticException if numeric overflow occurs (defined by the query) */ query(query) { assert(query != null, 'query() parameter must not be null', DateTimeException); if (query === TemporalQueries.chronology()) { return IsoChronology.INSTANCE; } else if (query === TemporalQueries.precision()) { return ChronoUnit.MONTHS; } return super.query(query); } /** * toString implementation... in JDK this is inherited from the Enum class * * @return {String} */ toString() { switch (this) { case Month.JANUARY: return 'JANUARY'; case Month.FEBRUARY: return 'FEBRUARY'; case Month.MARCH: return 'MARCH'; case Month.APRIL: return 'APRIL'; case Month.MAY: return 'MAY'; case Month.JUNE: return 'JUNE'; case Month.JULY: return 'JULY'; case Month.AUGUST: return 'AUGUST'; case Month.SEPTEMBER: return 'SEPTEMBER'; case Month.OCTOBER: return 'OCTOBER'; case Month.NOVEMBER: return 'NOVEMBER'; case Month.DECEMBER: return 'DECEMBER'; default: return `unknown Month, value: ${this.value()}`; } } /** * toJSON() use by JSON.stringify * delegates to toString() * * @return {string} */ toJSON() { return this.toString(); } /** * Adjusts the specified temporal object to have this month-of-year. * * This returns a temporal object of the same observable type as the input * with the month-of-year changed to be the same as this. * * The adjustment is equivalent to using {@link Temporal#with} * passing {@link ChronoField#MONTH_OF_YEAR} as the field. * If the specified temporal object does not use the ISO calendar system then * a {@link DateTimeException} is thrown. * * In most cases, it is clearer to reverse the calling pattern by using * {@link Temporal#with}: * <pre> * // these two lines are equivalent, but the second approach is recommended * temporal = thisMonth.adjustInto(temporal); * temporal = temporal.with(thisMonth); * </pre> * * For example, given a date in May, the following are output: * <pre> * dateInMay.with(JANUARY); // four months earlier * dateInMay.with(APRIL); // one months earlier * dateInMay.with(MAY); // same date * dateInMay.with(JUNE); // one month later * dateInMay.with(DECEMBER); // seven months later * </pre> * * This instance is immutable and unaffected by this method call. * * @param {Temporal} temporal - the target object to be adjusted, not null * @return {Temporal} the adjusted object, not null * @throws DateTimeException if unable to make the adjustment * @throws ArithmeticException if numeric overflow occurs */ adjustInto(temporal) { /* we support only ISO for now if (Chronology.from(temporal).equals(IsoChronology.INSTANCE) === false) { throw new DateTimeException('Adjustment only supported on ISO date-time'); } */ return temporal.with(ChronoField.MONTH_OF_YEAR, this.value()); } /** * Compares this Month to another Month. * * The comparison is based on the value of the Month. * It is "consistent with equals", as defined by {@link Comparable}. * * @param {Month} other the other year to compare to, not null * @return {number} the comparator value, negative if less, positive if greater */ compareTo(other) { requireNonNull(other, 'other'); requireInstance(other, Month, 'other'); return this._value - other._value; } /** * * @returns {boolean} */ equals(other){ return this === other; } /** * * @param {string} name * @returns {Month} */ static valueOf(name) { let ordinal = 0; for(ordinal; ordinal < MONTHS.length; ordinal++){ if(MONTHS[ordinal].name() === name){ break; } } return Month.of(ordinal+1); } /** * replacement for enum values * @return {Month[]} */ static values(){ return MONTHS.slice(); } /** * * @param {number} month * @return {Month} not null **/ static of(month) { if (month < 1 || month > 12) { assert(false, `Invalid value for MonthOfYear: ${month}`, DateTimeException); } return MONTHS[month-1]; } /** * Obtains an instance of {@link Month} from a temporal object. * * This obtains a month based on the specified temporal. * A {@link TemporalAccessor} represents an arbitrary set of date and time information, * which this factory converts to an instance of {@link Month}. * * The conversion extracts the MONTH_OF_YEAR (see {@link ChronoField#MONTH_OF_YEAR}) field. * The extraction is only permitted if the temporal object has an ISO * chronology, or can be converted to a {@link LocalDate}. * * This method matches the signature of the functional interface {@link TemporalQuery} * allowing it to be used in queries via method reference, {@link Month::from}. * * @param {TemporalAccessor} temporal the temporal object to convert, not null * @return {Month} the month-of-year, not null * @throws DateTimeException if unable to convert to a {@link Month} */ static from(temporal) { if (temporal instanceof Month) { return temporal; } try { /* only ISO for now if (IsoChronology.INSTANCE.equals(Chronology.from(temporal)) == false) { temporal = LocalDate.from(temporal); }*/ return Month.of(temporal.get(ChronoField.MONTH_OF_YEAR)); } catch (ex) { throw new DateTimeException(`Unable to obtain Month from TemporalAccessor: ${ temporal} of type ${temporal && temporal.constructor != null ? temporal.constructor.name : ''}`, ex); } } } let MONTHS; export function _init() { Month.JANUARY = new Month(1, 'JANUARY'); Month.FEBRUARY = new Month(2, 'FEBRUARY'); Month.MARCH = new Month(3, 'MARCH'); Month.APRIL = new Month(4, 'APRIL'); Month.MAY = new Month(5, 'MAY'); Month.JUNE = new Month(6, 'JUNE'); Month.JULY = new Month(7, 'JULY'); Month.AUGUST = new Month(8, 'AUGUST'); Month.SEPTEMBER = new Month(9, 'SEPTEMBER'); Month.OCTOBER = new Month(10, 'OCTOBER'); Month.NOVEMBER = new Month(11, 'NOVEMBER'); Month.DECEMBER = new Month(12, 'DECEMBER'); MONTHS = [ Month.JANUARY, Month.FEBRUARY, Month.MARCH, Month.APRIL, Month.MAY, Month.JUNE, Month.JULY, Month.AUGUST, Month.SEPTEMBER, Month.OCTOBER, Month.NOVEMBER, Month.DECEMBER ]; }