org.joda.time.DateTimeFieldType.java Source code

Java tutorial

Introduction

Here is the source code for org.joda.time.DateTimeFieldType.java

Source

/*
 *  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;
            }
        }
    }

}