/*
* 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 duration field, such as years or minutes, in a chronology-neutral way.
* <p>
* A duration field type defines the type of the field, such as hours.
* 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.
* <p>
* Instances of <code>DurationFieldType</code> are singletons.
* They can be compared using <code>==</code>.
* <p>
* If required, you can create your own field, for example a quarters.
* You must create a subclass of <code>DurationFieldType</code> that defines the field type.
* This class returns the actual calculation engine from {@link #getField(Chronology)}.
*
* @author Stephen Colebourne
* @author Brian S O'Neill
* @since 1.0
*/
public abstract class
DurationFieldType implements
Serializable {
/** Serialization version */
private static final long
serialVersionUID = 8765135187319L;
// Ordinals for standard field types.
static final byte
ERAS = 1,
CENTURIES = 2,
WEEKYEARS = 3,
YEARS = 4,
MONTHS = 5,
WEEKS = 6,
DAYS = 7,
HALFDAYS = 8,
HOURS = 9,
MINUTES = 10,
SECONDS = 11,
MILLIS = 12;
/** The eras field type. */
static final
DurationFieldType ERAS_TYPE = new
StandardDurationFieldType("eras",
ERAS);
/** The centuries field type. */
static final
DurationFieldType CENTURIES_TYPE = new
StandardDurationFieldType("centuries",
CENTURIES);
/** The weekyears field type. */
static final
DurationFieldType WEEKYEARS_TYPE = new
StandardDurationFieldType("weekyears",
WEEKYEARS);
/** The years field type. */
static final
DurationFieldType YEARS_TYPE = new
StandardDurationFieldType("years",
YEARS);
/** The months field type. */
static final
DurationFieldType MONTHS_TYPE = new
StandardDurationFieldType("months",
MONTHS);
/** The weeks field type. */
static final
DurationFieldType WEEKS_TYPE = new
StandardDurationFieldType("weeks",
WEEKS);
/** The days field type. */
static final
DurationFieldType DAYS_TYPE = new
StandardDurationFieldType("days",
DAYS);
/** The halfdays field type. */
static final
DurationFieldType HALFDAYS_TYPE = new
StandardDurationFieldType("halfdays",
HALFDAYS);
/** The hours field type. */
static final
DurationFieldType HOURS_TYPE = new
StandardDurationFieldType("hours",
HOURS);
/** The minutes field type. */
static final
DurationFieldType MINUTES_TYPE = new
StandardDurationFieldType("minutes",
MINUTES);
/** The seconds field type. */
static final
DurationFieldType SECONDS_TYPE = new
StandardDurationFieldType("seconds",
SECONDS);
/** The millis field type. */
static final
DurationFieldType MILLIS_TYPE = new
StandardDurationFieldType("millis",
MILLIS);
/** The name of the field type. */
private final
String iName;
//-----------------------------------------------------------------------
/**
* Constructor.
*
* @param name the name to use, which by convention, are plural.
*/
protected
DurationFieldType(
String name) {
super();
iName =
name;
}
//-----------------------------------------------------------------------
/**
* Get the millis field type.
*
* @return the DurationFieldType constant
*/
public static
DurationFieldType millis() {
return
MILLIS_TYPE;
}
/**
* Get the seconds field type.
*
* @return the DurationFieldType constant
*/
public static
DurationFieldType seconds() {
return
SECONDS_TYPE;
}
/**
* Get the minutes field type.
*
* @return the DurationFieldType constant
*/
public static
DurationFieldType minutes() {
return
MINUTES_TYPE;
}
/**
* Get the hours field type.
*
* @return the DurationFieldType constant
*/
public static
DurationFieldType hours() {
return
HOURS_TYPE;
}
/**
* Get the halfdays field type.
*
* @return the DurationFieldType constant
*/
public static
DurationFieldType halfdays() {
return
HALFDAYS_TYPE;
}
//-----------------------------------------------------------------------
/**
* Get the days field type.
*
* @return the DurationFieldType constant
*/
public static
DurationFieldType days() {
return
DAYS_TYPE;
}
/**
* Get the weeks field type.
*
* @return the DurationFieldType constant
*/
public static
DurationFieldType weeks() {
return
WEEKS_TYPE;
}
/**
* Get the weekyears field type.
*
* @return the DurationFieldType constant
*/
public static
DurationFieldType weekyears() {
return
WEEKYEARS_TYPE;
}
/**
* Get the months field type.
*
* @return the DurationFieldType constant
*/
public static
DurationFieldType months() {
return
MONTHS_TYPE;
}
/**
* Get the years field type.
*
* @return the DurationFieldType constant
*/
public static
DurationFieldType years() {
return
YEARS_TYPE;
}
/**
* Get the centuries field type.
*
* @return the DurationFieldType constant
*/
public static
DurationFieldType centuries() {
return
CENTURIES_TYPE;
}
/**
* Get the eras field type.
*
* @return the DurationFieldType constant
*/
public static
DurationFieldType eras() {
return
ERAS_TYPE;
}
//-----------------------------------------------------------------------
/**
* Get the name of the field.
* By convention, names are plural.
*
* @return field name
*/
public
String getName() {
return
iName;
}
/**
* 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
DurationField 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
StandardDurationFieldType extends
DurationFieldType {
/** Serialization version */
private static final long
serialVersionUID = 31156755687123L;
/** The ordinal of the standard field type, for switch statements */
private final byte
iOrdinal;
/**
* Constructor.
*
* @param name the name to use
*/
StandardDurationFieldType(
String name, byte
ordinal) {
super(
name);
iOrdinal =
ordinal;
}
/** @inheritdoc */
@
Override
public boolean
equals(
Object obj) {
if (this ==
obj) {
return true;
}
if (
obj instanceof
StandardDurationFieldType) {
return
iOrdinal == ((
StandardDurationFieldType)
obj).
iOrdinal;
}
return false;
}
/** @inheritdoc */
@
Override
public int
hashCode() {
return (1 <<
iOrdinal);
}
public
DurationField getField(
Chronology chronology) {
chronology =
DateTimeUtils.
getChronology(
chronology);
switch (
iOrdinal) {
case
ERAS:
return
chronology.
eras();
case
CENTURIES:
return
chronology.
centuries();
case
WEEKYEARS:
return
chronology.
weekyears();
case
YEARS:
return
chronology.
years();
case
MONTHS:
return
chronology.
months();
case
WEEKS:
return
chronology.
weeks();
case
DAYS:
return
chronology.
days();
case
HALFDAYS:
return
chronology.
halfdays();
case
HOURS:
return
chronology.
hours();
case
MINUTES:
return
chronology.
minutes();
case
SECONDS:
return
chronology.
seconds();
case
MILLIS:
return
chronology.
millis();
default:
// Shouldn't happen.
throw new
InternalError();
}
}
/**
* Ensure a singleton is returned.
*
* @return the singleton type
*/
private
Object readResolve() {
switch (
iOrdinal) {
case
ERAS:
return
ERAS_TYPE;
case
CENTURIES:
return
CENTURIES_TYPE;
case
WEEKYEARS:
return
WEEKYEARS_TYPE;
case
YEARS:
return
YEARS_TYPE;
case
MONTHS:
return
MONTHS_TYPE;
case
WEEKS:
return
WEEKS_TYPE;
case
DAYS:
return
DAYS_TYPE;
case
HALFDAYS:
return
HALFDAYS_TYPE;
case
HOURS:
return
HOURS_TYPE;
case
MINUTES:
return
MINUTES_TYPE;
case
SECONDS:
return
SECONDS_TYPE;
case
MILLIS:
return
MILLIS_TYPE;
default:
// Shouldn't happen.
return this;
}
}
}
}