Java tutorial
/* * Copyright 2001-2005 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; /** * Identifies a field, such as year or minuteOfHour, in a chronology-neutral way. * <p> * A field type defines the type of the field, such as hourOfDay. * If does not directly enable any calculations, however it does provide a * {@link #getField(Chronology)} method that returns the actual calculation engine * for a particular chronology. * It also provides access to the related {@link DurationFieldType}s. * <p> * Instances of <code>DateTimeFieldType</code> are singletons. * They can be compared using <code>==</code>. * <p> * If required, you can create your own field, for example a quarterOfYear. * You must create a subclass of <code>DateTimeFieldType</code> that defines the field type. * This class returns the actual calculation engine from {@link #getField(Chronology)}. * The subclass should implement equals and hashCode. * * @author Stephen Colebourne * @author Brian S O'Neill * @since 1.0 */ public abstract class DateTimeFieldType implements Serializable { /** Serialization version */ private static final long serialVersionUID = -42615285973990L; /** Ordinal values for standard field types. */ static final byte ERA = 1, YEAR_OF_ERA = 2, CENTURY_OF_ERA = 3, YEAR_OF_CENTURY = 4, YEAR = 5, DAY_OF_YEAR = 6, MONTH_OF_YEAR = 7, DAY_OF_MONTH = 8, WEEKYEAR_OF_CENTURY = 9, WEEKYEAR = 10, WEEK_OF_WEEKYEAR = 11, DAY_OF_WEEK = 12, HALFDAY_OF_DAY = 13, HOUR_OF_HALFDAY = 14, CLOCKHOUR_OF_HALFDAY = 15, CLOCKHOUR_OF_DAY = 16, HOUR_OF_DAY = 17, MINUTE_OF_DAY = 18, MINUTE_OF_HOUR = 19, SECOND_OF_DAY = 20, SECOND_OF_MINUTE = 21, MILLIS_OF_DAY = 22, MILLIS_OF_SECOND = 23; /** The era field type. */ private static final DateTimeFieldType ERA_TYPE = new StandardDateTimeFieldType("era", ERA, DurationFieldType.eras(), null); /** The yearOfEra field type. */ private static final DateTimeFieldType YEAR_OF_ERA_TYPE = new StandardDateTimeFieldType("yearOfEra", YEAR_OF_ERA, DurationFieldType.years(), DurationFieldType.eras()); /** The centuryOfEra field type. */ private static final DateTimeFieldType CENTURY_OF_ERA_TYPE = new StandardDateTimeFieldType("centuryOfEra", CENTURY_OF_ERA, DurationFieldType.centuries(), DurationFieldType.eras()); /** The yearOfCentury field type. */ private static final DateTimeFieldType YEAR_OF_CENTURY_TYPE = new StandardDateTimeFieldType("yearOfCentury", YEAR_OF_CENTURY, DurationFieldType.years(), DurationFieldType.centuries()); /** The year field type. */ private static final DateTimeFieldType YEAR_TYPE = new StandardDateTimeFieldType("year", YEAR, DurationFieldType.years(), null); /** The dayOfYear field type. */ private static final DateTimeFieldType DAY_OF_YEAR_TYPE = new StandardDateTimeFieldType("dayOfYear", DAY_OF_YEAR, DurationFieldType.days(), DurationFieldType.years()); /** The monthOfYear field type. */ private static final DateTimeFieldType MONTH_OF_YEAR_TYPE = new StandardDateTimeFieldType("monthOfYear", MONTH_OF_YEAR, DurationFieldType.months(), DurationFieldType.years()); /** The dayOfMonth field type. */ private static final DateTimeFieldType DAY_OF_MONTH_TYPE = new StandardDateTimeFieldType("dayOfMonth", DAY_OF_MONTH, DurationFieldType.days(), DurationFieldType.months()); /** The weekyearOfCentury field type. */ private static final DateTimeFieldType WEEKYEAR_OF_CENTURY_TYPE = new StandardDateTimeFieldType( "weekyearOfCentury", WEEKYEAR_OF_CENTURY, DurationFieldType.weekyears(), DurationFieldType.centuries()); /** The weekyear field type. */ private static final DateTimeFieldType WEEKYEAR_TYPE = new StandardDateTimeFieldType("weekyear", WEEKYEAR, DurationFieldType.weekyears(), null); /** The weekOfWeekyear field type. */ private static final DateTimeFieldType WEEK_OF_WEEKYEAR_TYPE = new StandardDateTimeFieldType("weekOfWeekyear", WEEK_OF_WEEKYEAR, DurationFieldType.weeks(), DurationFieldType.weekyears()); /** The dayOfWeek field type. */ private static final DateTimeFieldType DAY_OF_WEEK_TYPE = new StandardDateTimeFieldType("dayOfWeek", DAY_OF_WEEK, DurationFieldType.days(), DurationFieldType.weeks()); /** The halfday field type. */ private static final DateTimeFieldType HALFDAY_OF_DAY_TYPE = new StandardDateTimeFieldType("halfdayOfDay", HALFDAY_OF_DAY, DurationFieldType.halfdays(), DurationFieldType.days()); /** The hourOfHalfday field type. */ private static final DateTimeFieldType HOUR_OF_HALFDAY_TYPE = new StandardDateTimeFieldType("hourOfHalfday", HOUR_OF_HALFDAY, DurationFieldType.hours(), DurationFieldType.halfdays()); /** The clockhourOfHalfday field type. */ private static final DateTimeFieldType CLOCKHOUR_OF_HALFDAY_TYPE = new StandardDateTimeFieldType( "clockhourOfHalfday", CLOCKHOUR_OF_HALFDAY, DurationFieldType.hours(), DurationFieldType.halfdays()); /** The clockhourOfDay field type. */ private static final DateTimeFieldType CLOCKHOUR_OF_DAY_TYPE = new StandardDateTimeFieldType("clockhourOfDay", CLOCKHOUR_OF_DAY, DurationFieldType.hours(), DurationFieldType.days()); /** The hourOfDay field type. */ private static final DateTimeFieldType HOUR_OF_DAY_TYPE = new StandardDateTimeFieldType("hourOfDay", HOUR_OF_DAY, DurationFieldType.hours(), DurationFieldType.days()); /** The minuteOfDay field type. */ private static final DateTimeFieldType MINUTE_OF_DAY_TYPE = new StandardDateTimeFieldType("minuteOfDay", MINUTE_OF_DAY, DurationFieldType.minutes(), DurationFieldType.days()); /** The minuteOfHour field type. */ private static final DateTimeFieldType MINUTE_OF_HOUR_TYPE = new StandardDateTimeFieldType("minuteOfHour", MINUTE_OF_HOUR, DurationFieldType.minutes(), DurationFieldType.hours()); /** The secondOfDay field type. */ private static final DateTimeFieldType SECOND_OF_DAY_TYPE = new StandardDateTimeFieldType("secondOfDay", SECOND_OF_DAY, DurationFieldType.seconds(), DurationFieldType.days()); /** The secondOfMinute field type. */ private static final DateTimeFieldType SECOND_OF_MINUTE_TYPE = new StandardDateTimeFieldType("secondOfMinute", SECOND_OF_MINUTE, DurationFieldType.seconds(), DurationFieldType.minutes()); /** The millisOfDay field type. */ private static final DateTimeFieldType MILLIS_OF_DAY_TYPE = new StandardDateTimeFieldType("millisOfDay", MILLIS_OF_DAY, DurationFieldType.millis(), DurationFieldType.days()); /** The millisOfSecond field type. */ private static final DateTimeFieldType MILLIS_OF_SECOND_TYPE = new StandardDateTimeFieldType("millisOfSecond", MILLIS_OF_SECOND, DurationFieldType.millis(), DurationFieldType.seconds()); /** The name of the field. */ private final String iName; //----------------------------------------------------------------------- /** * Constructor. * * @param name the name to use */ protected DateTimeFieldType(String name) { super(); iName = name; } //----------------------------------------------------------------------- /** * Get the millis of second field type. * * @return the DateTimeFieldType constant */ public static DateTimeFieldType millisOfSecond() { return MILLIS_OF_SECOND_TYPE; } /** * Get the millis of day field type. * <p> * This measures the milliseconds from the start of the day on the <b>local</b> time-line. * On a daylight saving date, this means that some values will be missed (in spring) * or duplicated (in autumn/fall). * * @return the DateTimeFieldType constant */ public static DateTimeFieldType millisOfDay() { return MILLIS_OF_DAY_TYPE; } /** * Get the second of minute field type. * * @return the DateTimeFieldType constant */ public static DateTimeFieldType secondOfMinute() { return SECOND_OF_MINUTE_TYPE; } /** * Get the second of day field type. * <p> * This measures the seconds from the start of the day on the <b>local</b> time-line. * On a daylight saving date, this means that some values will be missed (in spring) * or duplicated (in autumn/fall). * * @return the DateTimeFieldType constant */ public static DateTimeFieldType secondOfDay() { return SECOND_OF_DAY_TYPE; } /** * Get the minute of hour field type. * * @return the DateTimeFieldType constant */ public static DateTimeFieldType minuteOfHour() { return MINUTE_OF_HOUR_TYPE; } /** * Get the minute of day field type. * <p> * This measures the minutes from the start of the day on the <b>local</b> time-line. * On a daylight saving date, this means that some values will be missed (in spring) * or duplicated (in autumn/fall). * * @return the DateTimeFieldType constant */ public static DateTimeFieldType minuteOfDay() { return MINUTE_OF_DAY_TYPE; } /** * Get the hour of day (0-23) field type. * * @return the DateTimeFieldType constant */ public static DateTimeFieldType hourOfDay() { return HOUR_OF_DAY_TYPE; } /** * Get the hour of day (offset to 1-24) field type. * * @return the DateTimeFieldType constant */ public static DateTimeFieldType clockhourOfDay() { return CLOCKHOUR_OF_DAY_TYPE; } /** * Get the hour of am/pm (0-11) field type. * * @return the DateTimeFieldType constant */ public static DateTimeFieldType hourOfHalfday() { return HOUR_OF_HALFDAY_TYPE; } /** * Get the hour of am/pm (offset to 1-12) field type. * * @return the DateTimeFieldType constant */ public static DateTimeFieldType clockhourOfHalfday() { return CLOCKHOUR_OF_HALFDAY_TYPE; } /** * Get the AM(0) PM(1) field type. * * @return the DateTimeFieldType constant */ public static DateTimeFieldType halfdayOfDay() { return HALFDAY_OF_DAY_TYPE; } //----------------------------------------------------------------------- /** * Get the day of week field type. * * @return the DateTimeFieldType constant */ public static DateTimeFieldType dayOfWeek() { return DAY_OF_WEEK_TYPE; } /** * Get the day of month field type. * * @return the DateTimeFieldType constant */ public static DateTimeFieldType dayOfMonth() { return DAY_OF_MONTH_TYPE; } /** * Get the day of year field type. * * @return the DateTimeFieldType constant */ public static DateTimeFieldType dayOfYear() { return DAY_OF_YEAR_TYPE; } /** * Get the week of a week based year field type. * * @return the DateTimeFieldType constant */ public static DateTimeFieldType weekOfWeekyear() { return WEEK_OF_WEEKYEAR_TYPE; } /** * Get the year of a week based year field type. * * @return the DateTimeFieldType constant */ public static DateTimeFieldType weekyear() { return WEEKYEAR_TYPE; } /** * Get the year of a week based year within a century field type. * * @return the DateTimeFieldType constant */ public static DateTimeFieldType weekyearOfCentury() { return WEEKYEAR_OF_CENTURY_TYPE; } /** * Get the month of year field type. * * @return the DateTimeFieldType constant */ public static DateTimeFieldType monthOfYear() { return MONTH_OF_YEAR_TYPE; } /** * Get the year field type. * * @return the DateTimeFieldType constant */ public static DateTimeFieldType year() { return YEAR_TYPE; } /** * Get the year of era field type. * * @return the DateTimeFieldType constant */ public static DateTimeFieldType yearOfEra() { return YEAR_OF_ERA_TYPE; } /** * Get the year of century field type. * * @return the DateTimeFieldType constant */ public static DateTimeFieldType yearOfCentury() { return YEAR_OF_CENTURY_TYPE; } /** * Get the century of era field type. * * @return the DateTimeFieldType constant */ public static DateTimeFieldType centuryOfEra() { return CENTURY_OF_ERA_TYPE; } /** * Get the era field type. * * @return the DateTimeFieldType constant */ public static DateTimeFieldType era() { return ERA_TYPE; } //----------------------------------------------------------------------- /** * Get the name of the field. * <p> * By convention, names follow a pattern of "dddOfRrr", where "ddd" represents * the (singular) duration unit field name and "Rrr" represents the (singular) * duration range field name. If the range field is not applicable, then * the name of the field is simply the (singular) duration field name. * * @return field name */ public String getName() { return iName; } /** * Get the duration unit of the field. * * @return duration unit of the field, never null */ public abstract DurationFieldType getDurationType(); /** * Get the duration range of the field. * * @return duration range of the field, null if unbounded */ public abstract DurationFieldType getRangeDurationType(); /** * Gets a suitable field for this type from the given Chronology. * * @param chronology the chronology to use, null means ISOChronology in default zone * @return a suitable field */ public abstract DateTimeField getField(Chronology chronology); /** * Checks whether this field supported in the given Chronology. * * @param chronology the chronology to use, null means ISOChronology in default zone * @return true if supported */ public boolean isSupported(Chronology chronology) { return getField(chronology).isSupported(); } /** * Get a suitable debug string. * * @return debug string */ public String toString() { return getName(); } private static class StandardDateTimeFieldType extends DateTimeFieldType { /** Serialization version */ private static final long serialVersionUID = -9937958251642L; /** The ordinal of the standard field type, for switch statements */ private final byte iOrdinal; /** The unit duration of the field. */ private final transient DurationFieldType iUnitType; /** The range duration of the field. */ private final transient DurationFieldType iRangeType; /** * Constructor. * * @param name the name to use * @param ordinal the byte value for the ordinal index * @param unitType the unit duration type * @param rangeType the range duration type */ StandardDateTimeFieldType(String name, byte ordinal, DurationFieldType unitType, DurationFieldType rangeType) { super(name); iOrdinal = ordinal; iUnitType = unitType; iRangeType = rangeType; } /** @inheritdoc */ public DurationFieldType getDurationType() { return iUnitType; } /** @inheritdoc */ public DurationFieldType getRangeDurationType() { return iRangeType; } /** @inheritdoc */ @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj instanceof StandardDateTimeFieldType) { return iOrdinal == ((StandardDateTimeFieldType) obj).iOrdinal; } return false; } /** @inheritdoc */ @Override public int hashCode() { return (1 << iOrdinal); } /** @inheritdoc */ public DateTimeField getField(Chronology chronology) { chronology = DateTimeUtils.getChronology(chronology); switch (iOrdinal) { case ERA: return chronology.era(); case YEAR_OF_ERA: return chronology.yearOfEra(); case CENTURY_OF_ERA: return chronology.centuryOfEra(); case YEAR_OF_CENTURY: return chronology.yearOfCentury(); case YEAR: return chronology.year(); case DAY_OF_YEAR: return chronology.dayOfYear(); case MONTH_OF_YEAR: return chronology.monthOfYear(); case DAY_OF_MONTH: return chronology.dayOfMonth(); case WEEKYEAR_OF_CENTURY: return chronology.weekyearOfCentury(); case WEEKYEAR: return chronology.weekyear(); case WEEK_OF_WEEKYEAR: return chronology.weekOfWeekyear(); case DAY_OF_WEEK: return chronology.dayOfWeek(); case HALFDAY_OF_DAY: return chronology.halfdayOfDay(); case HOUR_OF_HALFDAY: return chronology.hourOfHalfday(); case CLOCKHOUR_OF_HALFDAY: return chronology.clockhourOfHalfday(); case CLOCKHOUR_OF_DAY: return chronology.clockhourOfDay(); case HOUR_OF_DAY: return chronology.hourOfDay(); case MINUTE_OF_DAY: return chronology.minuteOfDay(); case MINUTE_OF_HOUR: return chronology.minuteOfHour(); case SECOND_OF_DAY: return chronology.secondOfDay(); case SECOND_OF_MINUTE: return chronology.secondOfMinute(); case MILLIS_OF_DAY: return chronology.millisOfDay(); case MILLIS_OF_SECOND: return chronology.millisOfSecond(); default: // Shouldn't happen. throw new InternalError(); } } /** * Ensure a singleton is returned. * * @return the singleton type */ private Object readResolve() { switch (iOrdinal) { case ERA: return ERA_TYPE; case YEAR_OF_ERA: return YEAR_OF_ERA_TYPE; case CENTURY_OF_ERA: return CENTURY_OF_ERA_TYPE; case YEAR_OF_CENTURY: return YEAR_OF_CENTURY_TYPE; case YEAR: return YEAR_TYPE; case DAY_OF_YEAR: return DAY_OF_YEAR_TYPE; case MONTH_OF_YEAR: return MONTH_OF_YEAR_TYPE; case DAY_OF_MONTH: return DAY_OF_MONTH_TYPE; case WEEKYEAR_OF_CENTURY: return WEEKYEAR_OF_CENTURY_TYPE; case WEEKYEAR: return WEEKYEAR_TYPE; case WEEK_OF_WEEKYEAR: return WEEK_OF_WEEKYEAR_TYPE; case DAY_OF_WEEK: return DAY_OF_WEEK_TYPE; case HALFDAY_OF_DAY: return HALFDAY_OF_DAY_TYPE; case HOUR_OF_HALFDAY: return HOUR_OF_HALFDAY_TYPE; case CLOCKHOUR_OF_HALFDAY: return CLOCKHOUR_OF_HALFDAY_TYPE; case CLOCKHOUR_OF_DAY: return CLOCKHOUR_OF_DAY_TYPE; case HOUR_OF_DAY: return HOUR_OF_DAY_TYPE; case MINUTE_OF_DAY: return MINUTE_OF_DAY_TYPE; case MINUTE_OF_HOUR: return MINUTE_OF_HOUR_TYPE; case SECOND_OF_DAY: return SECOND_OF_DAY_TYPE; case SECOND_OF_MINUTE: return SECOND_OF_MINUTE_TYPE; case MILLIS_OF_DAY: return MILLIS_OF_DAY_TYPE; case MILLIS_OF_SECOND: return MILLIS_OF_SECOND_TYPE; default: // Shouldn't happen. return this; } } } }