/* * Copyright 2001-2010 Stephen Colebourne * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.joda.time; import java.io.Serializable; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; import java.util.Locale; import org.joda.convert.FromString; import org.joda.convert.ToString; import org.joda.time.base.BasePartial; import org.joda.time.chrono.ISOChronology; import org.joda.time.field.AbstractPartialFieldProperty; import org.joda.time.field.FieldUtils; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; import org.joda.time.format.DateTimeFormatterBuilder; import org.joda.time.format.ISODateTimeFormat; /** * MonthDay is an immutable partial supporting the monthOfYear and dayOfMonth fields. *
* NOTE: This class only supports the two fields listed above. * It is impossible to query any other fields, such as dayOfWeek or centuryOfEra. *
* Calculations on MonthDay are performed using a {@link Chronology}. * This chronology is set to be in the UTC time zone for all calculations. *
* One use case for this class is to store a birthday without the year (to avoid * storing the age of the person). * This class can be used as the gMonthDay type in XML Schema. *
* Each individual field can be queried in two ways: *
getMonthOfYear()
* monthOfYear().get()
* monthOfYear().get()
* monthOfYear().getAsText()
* monthOfYear().getAsShortText()
* monthOfYear().getMaximumValue()
* monthOfYear().addToCopy()
* monthOfYear().setCopy()
*
* MonthDay is thread-safe and immutable, provided that the Chronology is as well.
* All standard Chronology classes supplied are thread-safe and immutable.
*
* @author Chris Pheby
* @since 2.0
*/
public final class MonthDay
extends BasePartial
implements ReadablePartial, Serializable {
/** Serialization version */
private static final long serialVersionUID = 2954560699050434609L;
/** The singleton set of field types */
private static final DateTimeFieldType[] FIELD_TYPES = new DateTimeFieldType[] {
DateTimeFieldType.monthOfYear(),
DateTimeFieldType.dayOfMonth(), };
/** The singleton set of field types */
private static final DateTimeFormatter PARSER = new DateTimeFormatterBuilder()
.appendOptional(ISODateTimeFormat.localDateParser().getParser())
.appendOptional(DateTimeFormat.forPattern("--MM-dd").getParser()).toFormatter();
/** The index of the monthOfYear field in the field array */
public static final int MONTH_OF_YEAR = 0;
/** The index of the day field in the field array */
public static final int DAY_OF_MONTH = 1;
//-----------------------------------------------------------------------
/**
* Obtains a {@code MonthDay} set to the current system millisecond time
* using ISOChronology
in the default time zone.
* The resulting object does not use the zone.
*
* @return the current month-day, not null
* @since 2.0
*/
public static MonthDay now() {
return new MonthDay();
}
/**
* Obtains a {@code MonthDay} set to the current system millisecond time
* using ISOChronology
in the specified time zone.
* The resulting object does not use the zone.
*
* @param zone the time zone, not null
* @return the current month-day, not null
* @since 2.0
*/
public static MonthDay now(DateTimeZone zone) {
if (zone == null) {
throw new NullPointerException("Zone must not be null");
}
return new MonthDay(zone);
}
/**
* Obtains a {@code MonthDay} set to the current system millisecond time
* using the specified chronology.
* The resulting object does not use the zone.
*
* @param chronology the chronology, not null
* @return the current month-day, not null
* @since 2.0
*/
public static MonthDay now(Chronology chronology) {
if (chronology == null) {
throw new NullPointerException("Chronology must not be null");
}
return new MonthDay(chronology);
}
//-----------------------------------------------------------------------
/**
* Parses a {@code MonthDay} from the specified string.
*
* This uses {@link ISODateTimeFormat#localDateParser()} or the format {@code --MM-dd}.
*
* @param str the string to parse, not null
* @since 2.0
*/
@FromString
public static MonthDay parse(String str) {
return parse(str, PARSER);
}
/**
* Parses a {@code MonthDay} from the specified string using a formatter.
*
* @param str the string to parse, not null
* @param formatter the formatter to use, not null
* @since 2.0
*/
public static MonthDay parse(String str, DateTimeFormatter formatter) {
LocalDate date = formatter.parseLocalDate(str);
return new MonthDay(date.getMonthOfYear(), date.getDayOfMonth());
}
//-----------------------------------------------------------------------
/**
* Constructs a MonthDay from a java.util.Calendar
* using exactly the same field values avoiding any time zone effects.
*
* Each field is queried from the Calendar and assigned to the MonthDay. *
* This factory method ignores the type of the calendar and always
* creates a MonthDay with ISO chronology. It is expected that you
* will only pass in instances of GregorianCalendar
however
* this is not validated.
*
* @param calendar the Calendar to extract fields from
* @return the created MonthDay, never null
* @throws IllegalArgumentException if the calendar is null
* @throws IllegalArgumentException if the monthOfYear or dayOfMonth is invalid for the ISO chronology
*/
public static MonthDay fromCalendarFields(Calendar calendar) {
if (calendar == null) {
throw new IllegalArgumentException("The calendar must not be null");
}
return new MonthDay(calendar.get(Calendar.MONTH) + 1, calendar.get(Calendar.DAY_OF_MONTH));
}
/**
* Constructs a MonthDay from a java.util.Date
* using exactly the same field values avoiding any time zone effects.
*
* Each field is queried from the Date and assigned to the MonthDay. *
* This factory method always creates a MonthDay with ISO chronology. * * @param date the Date to extract fields from * @return the created MonthDay, never null * @throws IllegalArgumentException if the calendar is null * @throws IllegalArgumentException if the monthOfYear or dayOfMonth is invalid for the ISO chronology */ @SuppressWarnings("deprecation") public static MonthDay fromDateFields(Date date) { if (date == null) { throw new IllegalArgumentException("The date must not be null"); } return new MonthDay(date.getMonth() + 1, date.getDate()); } //----------------------------------------------------------------------- /** * Constructs a MonthDay with the current monthOfYear, using ISOChronology in * the default zone to extract the fields. *
* The constructor uses the default time zone, resulting in the local time * being initialised. Once the constructor is complete, all further calculations * are performed without reference to a time-zone (by switching to UTC). * * @see #now() */ public MonthDay() { super(); } /** * Constructs a MonthDay with the current month-day, using ISOChronology in * the specified zone to extract the fields. *
* The constructor uses the specified time zone to obtain the current month-day. * Once the constructor is complete, all further calculations * are performed without reference to a time-zone (by switching to UTC). * * @param zone the zone to use, null means default zone * @see #now(DateTimeZone) */ public MonthDay(DateTimeZone zone) { super(ISOChronology.getInstance(zone)); } /** * Constructs a MonthDay with the current month-day, using the specified chronology * and zone to extract the fields. *
* The constructor uses the time zone of the chronology specified. * Once the constructor is complete, all further calculations are performed * without reference to a time-zone (by switching to UTC). * * @param chronology the chronology, null means ISOChronology in the default zone * @see #now(Chronology) */ public MonthDay(Chronology chronology) { super(chronology); } /** * Constructs a MonthDay extracting the partial fields from the specified * milliseconds using the ISOChronology in the default zone. *
* The constructor uses the default time zone, resulting in the local time * being initialised. Once the constructor is complete, all further calculations * are performed without reference to a time-zone (by switching to UTC). * * @param instant the milliseconds from 1970-01-01T00:00:00Z */ public MonthDay(long instant) { super(instant); } /** * Constructs a MonthDay extracting the partial fields from the specified * milliseconds using the chronology provided. *
* The constructor uses the time zone of the chronology specified. * Once the constructor is complete, all further calculations are performed * without reference to a time-zone (by switching to UTC). * * @param instant the milliseconds from 1970-01-01T00:00:00Z * @param chronology the chronology, null means ISOChronology in the default zone */ public MonthDay(long instant, Chronology chronology) { super(instant, chronology); } /** * Constructs a MonthDay from an Object that represents some form of time. *
* The recognised object types are defined in * {@link org.joda.time.convert.ConverterManager ConverterManager} and * include ReadableInstant, String, Calendar and Date. * The String formats are described by {@link ISODateTimeFormat#localDateParser()}. *
* The chronology used will be derived from the object, defaulting to ISO. * * @param instant the date-time object, null means now * @throws IllegalArgumentException if the instant is invalid */ public MonthDay(Object instant) { super(instant, null, ISODateTimeFormat.localDateParser()); } /** * Constructs a MonthDay from an Object that represents some form of time, * using the specified chronology. *
* The recognised object types are defined in * {@link org.joda.time.convert.ConverterManager ConverterManager} and * include ReadableInstant, String, Calendar and Date. * The String formats are described by {@link ISODateTimeFormat#localDateParser()}. *
* The constructor uses the time zone of the chronology specified.
* Once the constructor is complete, all further calculations are performed
* without reference to a time-zone (by switching to UTC).
* The specified chronology overrides that of the object.
*
* @param instant the date-time object, null means now
* @param chronology the chronology, null means ISO default
* @throws IllegalArgumentException if the instant is invalid
*/
public MonthDay(Object instant, Chronology chronology) {
super(instant, DateTimeUtils.getChronology(chronology), ISODateTimeFormat.localDateParser());
}
/**
* Constructs a MonthDay with specified year and month
* using ISOChronology
.
*
* The constructor uses the no time zone initialising the fields as provided. * Once the constructor is complete, all further calculations * are performed without reference to a time-zone (by switching to UTC). * * @param monthOfYear the month of the year * @param dayOfMonth the day of the month */ public MonthDay(int monthOfYear, int dayOfMonth) { this(monthOfYear, dayOfMonth, null); } /** * Constructs an instance set to the specified monthOfYear and dayOfMonth * using the specified chronology, whose zone is ignored. *
* If the chronology is null, ISOChronology
is used.
*
* The constructor uses the time zone of the chronology specified. * Once the constructor is complete, all further calculations are performed * without reference to a time-zone (by switching to UTC). * * @param monthOfYear the month of the year * @param dayOfMonth the day of the month * @param chronology the chronology, null means ISOChronology in the default zone */ public MonthDay(int monthOfYear, int dayOfMonth, Chronology chronology) { super(new int[] {monthOfYear, dayOfMonth}, chronology); } /** * Constructs a MonthDay with chronology from this instance and new values. * * @param partial the partial to base this new instance on * @param values the new set of values */ MonthDay(MonthDay partial, int[] values) { super(partial, values); } /** * Constructs a MonthDay with values from this instance and a new chronology. * * @param partial the partial to base this new instance on * @param chrono the new chronology */ MonthDay(MonthDay partial, Chronology chrono) { super(partial, chrono); } /** * Handle broken serialization from other tools. * @return the resolved object, not null */ private Object readResolve() { if (DateTimeZone.UTC.equals(getChronology().getZone()) == false) { return new MonthDay(this, getChronology().withUTC()); } return this; } //----------------------------------------------------------------------- /** * Gets the number of fields in this partial, which is two. * The supported fields are MonthOfYear and DayOfMonth. * Note that only these fields may be queried. * * @return the field count, two */ public int size() { return 2; } /** * Gets the field for a specific index in the chronology specified. *
* This method must not use any instance variables. * * @param index the index to retrieve * @param chrono the chronology to use * @return the field, never null */ protected DateTimeField getField(int index, Chronology chrono) { switch (index) { case MONTH_OF_YEAR: return chrono.monthOfYear(); case DAY_OF_MONTH: return chrono.dayOfMonth(); default: throw new IndexOutOfBoundsException("Invalid index: " + index); } } /** * Gets the field type at the specified index. * * @param index the index to retrieve * @return the field at the specified index, never null * @throws IndexOutOfBoundsException if the index is invalid */ public DateTimeFieldType getFieldType(int index) { return FIELD_TYPES[index]; } /** * Gets an array of the field type of each of the fields that this partial supports. *
* The fields are returned largest to smallest, Month, Day. * * @return the array of field types (cloned), largest to smallest, never null */ public DateTimeFieldType[] getFieldTypes() { return (DateTimeFieldType[]) FIELD_TYPES.clone(); } //----------------------------------------------------------------------- /** * Returns a copy of this month-day with the specified chronology. * This instance is immutable and unaffected by this method call. *
* This method retains the values of the fields, thus the result will * typically refer to a different instant. *
* The time zone of the specified chronology is ignored, as MonthDay * operates without a time zone. * * @param newChronology the new chronology, null means ISO * @return a copy of this month-day with a different chronology, never null * @throws IllegalArgumentException if the values are invalid for the new chronology */ public MonthDay withChronologyRetainFields(Chronology newChronology) { newChronology = DateTimeUtils.getChronology(newChronology); newChronology = newChronology.withUTC(); if (newChronology == getChronology()) { return this; } else { MonthDay newMonthDay = new MonthDay(this, newChronology); newChronology.validate(newMonthDay, getValues()); return newMonthDay; } } /** * Returns a copy of this month-day with the specified field set to a new value. *
* For example, if the field type is dayOfMonth
then the day
* would be changed in the returned instance.
*
* These three lines are equivalent: *
* MonthDay updated = md.withField(DateTimeFieldType.dayOfMonth(), 6); * MonthDay updated = md.dayOfMonth().setCopy(6); * MonthDay updated = md.property(DateTimeFieldType.dayOfMonth()).setCopy(6); ** * @param fieldType the field type to set, not null * @param value the value to set * @return a copy of this instance with the field set, never null * @throws IllegalArgumentException if the value is null or invalid */ public MonthDay withField(DateTimeFieldType fieldType, int value) { int index = indexOfSupported(fieldType); if (value == getValue(index)) { return this; } int[] newValues = getValues(); newValues = getField(index).set(this, index, newValues, value); return new MonthDay(this, newValues); } /** * Returns a copy of this month-day with the value of the specified field increased. *
* If the addition is zero, then this
is returned.
*
* These three lines are equivalent: *
* MonthDay added = md.withFieldAdded(DurationFieldType.days(), 6); * MonthDay added = md.plusDays(6); * MonthDay added = md.dayOfMonth().addToCopy(6); ** * @param fieldType the field type to add to, not null * @param amount the amount to add * @return a copy of this instance with the field updated, never null * @throws IllegalArgumentException if the value is null or invalid * @throws ArithmeticException if the new date-time exceeds the capacity */ public MonthDay withFieldAdded(DurationFieldType fieldType, int amount) { int index = indexOfSupported(fieldType); if (amount == 0) { return this; } int[] newValues = getValues(); newValues = getField(index).add(this, index, newValues, amount); return new MonthDay(this, newValues); } /** * Returns a copy of this month-day with the specified period added. *
* If the addition is zero, then this
is returned.
* Fields in the period that aren't present in the partial are ignored.
*
* This method is typically used to add multiple copies of complex * period instances. Adding one field is best achieved using methods * like {@link #withFieldAdded(DurationFieldType, int)} * or {@link #plusMonths(int)}. * * @param period the period to add to this one, null means zero * @param scalar the amount of times to add, such as -1 to subtract once * @return a copy of this instance with the period added, never null * @throws ArithmeticException if the new date-time exceeds the capacity */ public MonthDay withPeriodAdded(ReadablePeriod period, int scalar) { if (period == null || scalar == 0) { return this; } int[] newValues = getValues(); for (int i = 0; i < period.size(); i++) { DurationFieldType fieldType = period.getFieldType(i); int index = indexOf(fieldType); if (index >= 0) { newValues = getField(index).add(this, index, newValues, FieldUtils.safeMultiply(period.getValue(i), scalar)); } } return new MonthDay(this, newValues); } //----------------------------------------------------------------------- /** * Returns a copy of this month-day with the specified period added. *
* If the amount is zero or null, then this
is returned.
*
* This method is typically used to add complex period instances. * Adding one field is best achieved using methods * like {@link #plusMonths(int)}. * * @param period the duration to add to this one, null means zero * @return a copy of this instance with the period added, never null * @throws ArithmeticException if the new month-day exceeds the capacity */ public MonthDay plus(ReadablePeriod period) { return withPeriodAdded(period, 1); } //----------------------------------------------------------------------- /** * Returns a copy of this month-day plus the specified number of months. *
* This month-day instance is immutable and unaffected by this method call. * The month will wrap at the end of the year from December to January. * The day will be adjusted to the last valid value if necessary. *
* The following three lines are identical in effect: *
* MonthDay added = md.plusMonths(6); * MonthDay added = md.plus(Period.months(6)); * MonthDay added = md.withFieldAdded(DurationFieldType.months(), 6); ** * @param months the amount of months to add, may be negative * @return the new month-day plus the increased months, never null */ public MonthDay plusMonths(int months) { return withFieldAdded(DurationFieldType.months(), months); } /** * Returns a copy of this month-day plus the specified number of days. *
* This month-day instance is immutable and unaffected by this method call. * The month will wrap at the end of the year from December to January. *
* The following three lines are identical in effect: *
* MonthDay added = md.plusDays(6); * MonthDay added = md.plus(Period.days(6)); * MonthDay added = md.withFieldAdded(DurationFieldType.days(), 6); ** * @param days the amount of days to add, may be negative * @return the new month-day plus the increased days, never null */ public MonthDay plusDays(int days) { return withFieldAdded(DurationFieldType.days(), days); } //----------------------------------------------------------------------- /** * Returns a copy of this month-day with the specified period taken away. *
* If the amount is zero or null, then this
is returned.
*
* This method is typically used to subtract complex period instances. * Subtracting one field is best achieved using methods * like {@link #minusMonths(int)}. * * @param period the period to reduce this instant by * @return a copy of this instance with the period taken away, never null * @throws ArithmeticException if the new month-day exceeds the capacity */ public MonthDay minus(ReadablePeriod period) { return withPeriodAdded(period, -1); } //----------------------------------------------------------------------- /** * Returns a copy of this month-day minus the specified number of months. *
* This MonthDay instance is immutable and unaffected by this method call. * The month will wrap at the end of the year from January to December. * The day will be adjusted to the last valid value if necessary. *
* The following three lines are identical in effect: *
* MonthDay subtracted = md.minusMonths(6); * MonthDay subtracted = md.minus(Period.months(6)); * MonthDay subtracted = md.withFieldAdded(DurationFieldType.months(), -6); ** * @param months the amount of months to subtract, may be negative * @return the new month-day minus the increased months, never null */ public MonthDay minusMonths(int months) { return withFieldAdded(DurationFieldType.months(), FieldUtils.safeNegate(months)); } /** * Returns a copy of this month-day minus the specified number of months. *
* This month-day instance is immutable and unaffected by this method call. * The month will wrap at the end of the year from January to December. *
* The following three lines are identical in effect: *
* MonthDay subtracted = md.minusDays(6); * MonthDay subtracted = md.minus(Period.days(6)); * MonthDay subtracted = md.withFieldAdded(DurationFieldType.days(), -6); ** * @param days the amount of days to subtract, may be negative * @return the new month-day minus the increased days, never null */ public MonthDay minusDays(int days) { return withFieldAdded(DurationFieldType.days(), FieldUtils.safeNegate(days)); } //----------------------------------------------------------------------- /** * Converts this object to a LocalDate with the same month-day and chronology. * * @param year the year to use, valid for chronology * @return a LocalDate with the same month-day and chronology, never null */ public LocalDate toLocalDate(int year) { return new LocalDate(year, getMonthOfYear(), getDayOfMonth(), getChronology()); } //----------------------------------------------------------------------- /** * Get the month of year field value. * * @return the month of year */ public int getMonthOfYear() { return getValue(MONTH_OF_YEAR); } /** * Get the day of month field value. * * @return the day of month */ public int getDayOfMonth() { return getValue(DAY_OF_MONTH); } //----------------------------------------------------------------------- /** * Returns a copy of this month-day with the month of year field updated. *
* MonthDay is immutable, so there are no set methods. * Instead, this method returns a new instance with the value of * month of year changed. * * @param monthOfYear the month of year to set * @return a copy of this object with the field set, never null * @throws IllegalArgumentException if the value is invalid */ public MonthDay withMonthOfYear(int monthOfYear) { int[] newValues = getValues(); newValues = getChronology().monthOfYear().set(this, MONTH_OF_YEAR, newValues, monthOfYear); return new MonthDay(this, newValues); } /** * Returns a copy of this month-day with the day of month field updated. *
* MonthDay is immutable, so there are no set methods.
* Instead, this method returns a new instance with the value of
* day of month changed.
*
* @param dayOfMonth the day of month to set
* @return a copy of this object with the field set, never null
* @throws IllegalArgumentException if the value is invalid
*/
public MonthDay withDayOfMonth(int dayOfMonth) {
int[] newValues = getValues();
newValues = getChronology().dayOfMonth().set(this, DAY_OF_MONTH, newValues, dayOfMonth);
return new MonthDay(this, newValues);
}
//-----------------------------------------------------------------------
/**
* Gets the property object for the specified type, which contains
* many useful methods.
*
* @param type the field type to get the property for
* @return the property object
* @throws IllegalArgumentException if the field is null or unsupported
*/
public Property property(DateTimeFieldType type) {
return new Property(this, indexOfSupported(type));
}
//-----------------------------------------------------------------------
/**
* Get the month of year field property which provides access to advanced functionality.
*
* @return the month of year property
*/
public Property monthOfYear() {
return new Property(this, MONTH_OF_YEAR);
}
/**
* Get the day of month field property which provides access to advanced functionality.
*
* @return the day of month property
*/
public Property dayOfMonth() {
return new Property(this, DAY_OF_MONTH);
}
//-----------------------------------------------------------------------
/**
* Output the month-day in ISO8601 format (--MM-dd).
*
* @return ISO8601 time formatted string.
*/
@ToString
public String toString() {
List
* This class binds a
* The value will be added to this field. If the value is too large to be
* added solely to this field then it will affect larger fields.
* Smaller fields are unaffected.
*
* The MonthDay attached to this property is unchanged by this call.
* Instead, a new instance is returned.
*
* @param valueToAdd the value to add to the field in the copy
* @return a copy of the MonthDay with the field value changed
* @throws IllegalArgumentException if the value isn't valid
*/
public MonthDay addToCopy(int valueToAdd) {
int[] newValues = iBase.getValues();
newValues = getField().add(iBase, iFieldIndex, newValues, valueToAdd);
return new MonthDay(iBase, newValues);
}
/**
* Adds to the value of this field in a copy of this MonthDay wrapping
* within this field if the maximum value is reached.
*
* The value will be added to this field. If the value is too large to be
* added solely to this field then it wraps within this field.
* Other fields are unaffected.
*
* For example,
*
* The MonthDay attached to this property is unchanged by this call.
* Instead, a new instance is returned.
*
* @param valueToAdd the value to add to the field in the copy
* @return a copy of the MonthDay with the field value changed
* @throws IllegalArgumentException if the value isn't valid
*/
public MonthDay addWrapFieldToCopy(int valueToAdd) {
int[] newValues = iBase.getValues();
newValues = getField().addWrapField(iBase, iFieldIndex, newValues, valueToAdd);
return new MonthDay(iBase, newValues);
}
//-----------------------------------------------------------------------
/**
* Sets this field in a copy of the MonthDay.
*
* The MonthDay attached to this property is unchanged by this call.
* Instead, a new instance is returned.
*
* @param value the value to set the field in the copy to
* @return a copy of the MonthDay with the field value changed
* @throws IllegalArgumentException if the value isn't valid
*/
public MonthDay setCopy(int value) {
int[] newValues = iBase.getValues();
newValues = getField().set(iBase, iFieldIndex, newValues, value);
return new MonthDay(iBase, newValues);
}
/**
* Sets this field in a copy of the MonthDay to a parsed text value.
*
* The MonthDay attached to this property is unchanged by this call.
* Instead, a new instance is returned.
*
* @param text the text value to set
* @param locale optional locale to use for selecting a text symbol
* @return a copy of the MonthDay with the field value changed
* @throws IllegalArgumentException if the text value isn't valid
*/
public MonthDay setCopy(String text, Locale locale) {
int[] newValues = iBase.getValues();
newValues = getField().set(iBase, iFieldIndex, newValues, text, locale);
return new MonthDay(iBase, newValues);
}
/**
* Sets this field in a copy of the MonthDay to a parsed text value.
*
* The MonthDay attached to this property is unchanged by this call.
* Instead, a new instance is returned.
*
* @param text the text value to set
* @return a copy of the MonthDay with the field value changed
* @throws IllegalArgumentException if the text value isn't valid
*/
public MonthDay setCopy(String text) {
return setCopy(text, null);
}
}
}
toString
* @see org.joda.time.format.DateTimeFormat
*/
public String toString(String pattern) {
if (pattern == null) {
return toString();
}
return DateTimeFormat.forPattern(pattern).print(this);
}
/**
* Output the month-day using the specified format pattern.
*
* @param pattern the pattern specification, null means use toString
* @param locale Locale to use, null means default
* @see org.joda.time.format.DateTimeFormat
*/
public String toString(String pattern, Locale locale) throws IllegalArgumentException {
if (pattern == null) {
return toString();
}
return DateTimeFormat.forPattern(pattern).withLocale(locale).print(this);
}
//-----------------------------------------------------------------------
/**
* The property class for MonthDay
.
* YearMonth
to a DateTimeField
.
*
* @author Chris Pheby
* @since 2.0
*/
public static class Property extends AbstractPartialFieldProperty implements Serializable {
/** Serialization version */
private static final long serialVersionUID = 5727734012190224363L;
/** The partial */
private final MonthDay iBase;
/** The field index */
private final int iFieldIndex;
/**
* Constructs a property.
*
* @param partial the partial instance
* @param fieldIndex the index in the partial
*/
Property(MonthDay partial, int fieldIndex) {
super();
iBase = partial;
iFieldIndex = fieldIndex;
}
/**
* Gets the field that this property uses.
*
* @return the field
*/
public DateTimeField getField() {
return iBase.getField(iFieldIndex);
}
/**
* Gets the partial that this property belongs to.
*
* @return the partial
*/
protected ReadablePartial getReadablePartial() {
return iBase;
}
/**
* Gets the partial that this property belongs to.
*
* @return the partial
*/
public MonthDay getMonthDay() {
return iBase;
}
/**
* Gets the value of this field.
*
* @return the field value
*/
public int get() {
return iBase.getValue(iFieldIndex);
}
//-----------------------------------------------------------------------
/**
* Adds to the value of this field in a copy of this MonthDay.
* --12-30
addWrapField one month returns --01-30
.
*