/*
* Copyright 2001-2009 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;
/**
* Defines the calculation engine for duration fields.
* The interface defines a set of methods that manipulate a millisecond duration
* with regards to a single field, such as months or seconds.
* <p>
* This design is extensible so, if you wish, you can extract a different field from
* the millisecond duration. A number of standard implementations are provided to assist.
*
* @author Stephen Colebourne
* @author Brian S O'Neill
* @since 1.0
*/
public abstract class DurationField implements Comparable<DurationField> {
/**
* Get the type of the field.
*
* @return field type
*/
public abstract DurationFieldType getType();
/**
* Get the name of the field.
* <p>
* By convention, names are plural.
*
* @return field name
*/
public abstract String getName();
/**
* Returns true if this field is supported.
*
* @return true if this field is supported
*/
public abstract boolean isSupported();
/**
* Is this field precise. A precise field can calculate its value from
* milliseconds without needing a reference date. Put another way, a
* precise field's unit size is not variable.
*
* @return true if precise
* @see #getUnitMillis()
*/
public abstract boolean isPrecise();
/**
* Returns the amount of milliseconds per unit value of this field. For
* example, if this field represents "seconds", then this returns the
* milliseconds in one second.
* <p>
* For imprecise fields, the unit size is variable, and so this method
* returns a suitable average value.
*
* @return the unit size of this field, in milliseconds
* @see #isPrecise()
*/
public abstract long getUnitMillis();
//------------------------------------------------------------------------
/**
* Get the value of this field from the milliseconds, which is approximate
* if this field is imprecise.
*
* @param duration the milliseconds to query, which may be negative
* @return the value of the field, in the units of the field, which may be
* negative
* @throws ArithmeticException if the value is too large for an int
*/
public abstract int getValue(long duration);
/**
* Get the value of this field from the milliseconds, which is approximate
* if this field is imprecise.
*
* @param duration the milliseconds to query, which may be negative
* @return the value of the field, in the units of the field, which may be
* negative
*/
public abstract long getValueAsLong(long duration);
/**
* Get the value of this field from the milliseconds relative to an
* instant. For precise fields this method produces the same result as for
* the single argument get method.
* <p>
* If the millisecond duration is positive, then the instant is treated as a
* "start instant". If negative, the instant is treated as an "end instant".
*
* @param duration the milliseconds to query, which may be negative
* @param instant the start instant to calculate relative to
* @return the value of the field, in the units of the field, which may be
* negative
* @throws ArithmeticException if the value is too large for an int
*/
public abstract int getValue(long duration, long instant);
/**
* Get the value of this field from the milliseconds relative to an
* instant. For precise fields this method produces the same result as for
* the single argument get method.
* <p>
* If the millisecond duration is positive, then the instant is treated as a
* "start instant". If negative, the instant is treated as an "end instant".
*
* @param duration the milliseconds to query, which may be negative
* @param instant the start instant to calculate relative to
* @return the value of the field, in the units of the field, which may be
* negative
*/
public abstract long getValueAsLong(long duration, long instant);
//------------------------------------------------------------------------
/**
* Get the millisecond duration of this field from its value, which is
* approximate if this field is imprecise.
*
* @param value the value of the field, which may be negative
* @return the milliseconds that the field represents, which may be
* negative
*/
public abstract long getMillis(int value);
/**
* Get the millisecond duration of this field from its value, which is
* approximate if this field is imprecise.
*
* @param value the value of the field, which may be negative
* @return the milliseconds that the field represents, which may be
* negative
*/
public abstract long getMillis(long value);
/**
* Get the millisecond duration of this field from its value relative to an
* instant. For precise fields this method produces the same result as for
* the single argument getMillis method.
* <p>
* If the value is positive, then the instant is treated as a "start
* instant". If negative, the instant is treated as an "end instant".
*
* @param value the value of the field, which may be negative
* @param instant the instant to calculate relative to
* @return the millisecond duration that the field represents, which may be
* negative
*/
public abstract long getMillis(int value, long instant);
/**
* Get the millisecond duration of this field from its value relative to an
* instant. For precise fields this method produces the same result as for
* the single argument getMillis method.
* <p>
* If the value is positive, then the instant is treated as a "start
* instant". If negative, the instant is treated as an "end instant".
*
* @param value the value of the field, which may be negative
* @param instant the instant to calculate relative to
* @return the millisecond duration that the field represents, which may be
* negative
*/
public abstract long getMillis(long value, long instant);
/**
* Adds a duration value (which may be negative) to the instant.
*
* @param instant the milliseconds from 1970-01-01T00:00:00Z to add to
* @param value the value to add, in the units of the field
* @return the updated milliseconds
*/
public abstract long add(long instant, int value);
/**
* Adds a duration value (which may be negative) to the instant.
*
* @param instant the milliseconds from 1970-01-01T00:00:00Z to add to
* @param value the value to add, in the units of the field
* @return the updated milliseconds
*/
public abstract long add(long instant, long value);
/**
* Subtracts a duration value (which may be negative) from the instant.
*
* @param instant the milliseconds from 1970-01-01T00:00:00Z to subtract from
* @param value the value to subtract, in the units of the field
* @return the updated milliseconds
* @since 1.1
*/
public long subtract(long instant, int value) {
if (value == Integer.MIN_VALUE) {
return subtract(instant, (long) value);
}
return add(instant, -value);
}
/**
* Subtracts a duration value (which may be negative) from the instant.
*
* @param instant the milliseconds from 1970-01-01T00:00:00Z to subtract from
* @param value the value to subtract, in the units of the field
* @return the updated milliseconds
* @since 1.1
*/
public long subtract(long instant, long value) {
if (value == Long.MIN_VALUE) {
throw new ArithmeticException("Long.MIN_VALUE cannot be negated");
}
return add(instant, -value);
}
/**
* Computes the difference between two instants, as measured in the units
* of this field. Any fractional units are dropped from the result. Calling
* getDifference reverses the effect of calling add. In the following code:
*
* <pre>
* long instant = ...
* int v = ...
* int age = getDifference(add(instant, v), instant);
* </pre>
*
* The value 'age' is the same as the value 'v'.
*
* @param minuendInstant the milliseconds from 1970-01-01T00:00:00Z to
* subtract from
* @param subtrahendInstant the milliseconds from 1970-01-01T00:00:00Z to
* subtract off the minuend
* @return the difference in the units of this field
*/
public abstract int getDifference(long minuendInstant, long subtrahendInstant);
/**
* Computes the difference between two instants, as measured in the units
* of this field. Any fractional units are dropped from the result. Calling
* getDifference reverses the effect of calling add. In the following code:
*
* <pre>
* long instant = ...
* long v = ...
* long age = getDifferenceAsLong(add(instant, v), instant);
* </pre>
*
* The value 'age' is the same as the value 'v'.
*
* @param minuendInstant the milliseconds from 1970-01-01T00:00:00Z to
* subtract from
* @param subtrahendInstant the milliseconds from 1970-01-01T00:00:00Z to
* subtract off the minuend
* @return the difference in the units of this field
*/
public abstract long getDifferenceAsLong(long minuendInstant, long subtrahendInstant);
// Adding this definition would be backwards incompatible with earlier subclasses
// This definition of compareTo was present in previous versions, and still applies
// /**
// * Compares this duration field with another duration field for ascending
// * unit millisecond order. This ordering is inconsistent with equals, as it
// * ignores name and precision.
// *
// * @param durationField a duration field to check against
// * @return negative value if this is less, 0 if equal, or positive value if greater
// * @throws NullPointerException if the object is null
// * @throws ClassCastException if the object type is not supported
// */
// public abstract int compareTo(DurationField durationField);
/**
* Returns a localized unit name of this field, using the given value as an
* aid. For example, the unit name may differ if it is plural.
*
* @param value the duration value to use for selecting a unit name
* @param locale the locale to use for selecting a name, null for default
*/
//String getUnitName(long value, Locale locale);
/**
* Returns a localized unit name of this field, using the given value as an
* aid. For example, the unit name may differ if it is plural.
*
* @param value the duration value to use for selecting a unit name
*/
//String getUnitName(long value);
/**
* Get the maximum length string returned by getUnitName.
*
* @param locale the locale to use for selecting a unit name, null for
* default
* @return the maximum name length
*/
//int getMaximumUnitNameLength(Locale locale);
//------------------------------------------------------------------------
/**
* Get a suitable debug string.
*
* @return debug string
*/
public abstract String toString();
}