001: /*
002: * Copyright 2001-2005 Stephen Colebourne
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.joda.time;
017:
018: /**
019: * Defines the calculation engine for duration fields.
020: * The interface defines a set of methods that manipulate a millisecond duration
021: * with regards to a single field, such as months or seconds.
022: * <p>
023: * This design is extensible so, if you wish, you can extract a different field from
024: * the millisecond duration. A number of standard implementations are provided to assist.
025: *
026: * @author Stephen Colebourne
027: * @author Brian S O'Neill
028: * @since 1.0
029: */
030: public abstract class DurationField implements Comparable {
031:
032: /**
033: * Get the type of the field.
034: *
035: * @return field type
036: */
037: public abstract DurationFieldType getType();
038:
039: /**
040: * Get the name of the field.
041: * <p>
042: * By convention, names are plural.
043: *
044: * @return field name
045: */
046: public abstract String getName();
047:
048: /**
049: * Returns true if this field is supported.
050: *
051: * @return true if this field is supported
052: */
053: public abstract boolean isSupported();
054:
055: /**
056: * Is this field precise. A precise field can calculate its value from
057: * milliseconds without needing a reference date. Put another way, a
058: * precise field's unit size is not variable.
059: *
060: * @return true if precise
061: * @see #getUnitMillis()
062: */
063: public abstract boolean isPrecise();
064:
065: /**
066: * Returns the amount of milliseconds per unit value of this field. For
067: * example, if this field represents "seconds", then this returns the
068: * milliseconds in one second.
069: * <p>
070: * For imprecise fields, the unit size is variable, and so this method
071: * returns a suitable average value.
072: *
073: * @return the unit size of this field, in milliseconds
074: * @see #isPrecise()
075: */
076: public abstract long getUnitMillis();
077:
078: //------------------------------------------------------------------------
079: /**
080: * Get the value of this field from the milliseconds, which is approximate
081: * if this field is imprecise.
082: *
083: * @param duration the milliseconds to query, which may be negative
084: * @return the value of the field, in the units of the field, which may be
085: * negative
086: * @throws ArithmeticException if the value is too large for an int
087: */
088: public abstract int getValue(long duration);
089:
090: /**
091: * Get the value of this field from the milliseconds, which is approximate
092: * if this field is imprecise.
093: *
094: * @param duration the milliseconds to query, which may be negative
095: * @return the value of the field, in the units of the field, which may be
096: * negative
097: */
098: public abstract long getValueAsLong(long duration);
099:
100: /**
101: * Get the value of this field from the milliseconds relative to an
102: * instant. For precise fields this method produces the same result as for
103: * the single argument get method.
104: * <p>
105: * If the millisecond duration is positive, then the instant is treated as a
106: * "start instant". If negative, the instant is treated as an "end instant".
107: *
108: * @param duration the milliseconds to query, which may be negative
109: * @param instant the start instant to calculate relative to
110: * @return the value of the field, in the units of the field, which may be
111: * negative
112: * @throws ArithmeticException if the value is too large for an int
113: */
114: public abstract int getValue(long duration, long instant);
115:
116: /**
117: * Get the value of this field from the milliseconds relative to an
118: * instant. For precise fields this method produces the same result as for
119: * the single argument get method.
120: * <p>
121: * If the millisecond duration is positive, then the instant is treated as a
122: * "start instant". If negative, the instant is treated as an "end instant".
123: *
124: * @param duration the milliseconds to query, which may be negative
125: * @param instant the start instant to calculate relative to
126: * @return the value of the field, in the units of the field, which may be
127: * negative
128: */
129: public abstract long getValueAsLong(long duration, long instant);
130:
131: //------------------------------------------------------------------------
132: /**
133: * Get the millisecond duration of this field from its value, which is
134: * approximate if this field is imprecise.
135: *
136: * @param value the value of the field, which may be negative
137: * @return the milliseconds that the field represents, which may be
138: * negative
139: */
140: public abstract long getMillis(int value);
141:
142: /**
143: * Get the millisecond duration of this field from its value, which is
144: * approximate if this field is imprecise.
145: *
146: * @param value the value of the field, which may be negative
147: * @return the milliseconds that the field represents, which may be
148: * negative
149: */
150: public abstract long getMillis(long value);
151:
152: /**
153: * Get the millisecond duration of this field from its value relative to an
154: * instant. For precise fields this method produces the same result as for
155: * the single argument getMillis method.
156: * <p>
157: * If the value is positive, then the instant is treated as a "start
158: * instant". If negative, the instant is treated as an "end instant".
159: *
160: * @param value the value of the field, which may be negative
161: * @param instant the instant to calculate relative to
162: * @return the millisecond duration that the field represents, which may be
163: * negative
164: */
165: public abstract long getMillis(int value, long instant);
166:
167: /**
168: * Get the millisecond duration of this field from its value relative to an
169: * instant. For precise fields this method produces the same result as for
170: * the single argument getMillis method.
171: * <p>
172: * If the value is positive, then the instant is treated as a "start
173: * instant". If negative, the instant is treated as an "end instant".
174: *
175: * @param value the value of the field, which may be negative
176: * @param instant the instant to calculate relative to
177: * @return the millisecond duration that the field represents, which may be
178: * negative
179: */
180: public abstract long getMillis(long value, long instant);
181:
182: /**
183: * Adds a duration value (which may be negative) to the instant.
184: *
185: * @param instant the milliseconds from 1970-01-01T00:00:00Z to add to
186: * @param value the value to add, in the units of the field
187: * @return the updated milliseconds
188: */
189: public abstract long add(long instant, int value);
190:
191: /**
192: * Adds a duration value (which may be negative) to the instant.
193: *
194: * @param instant the milliseconds from 1970-01-01T00:00:00Z to add to
195: * @param value the value to add, in the units of the field
196: * @return the updated milliseconds
197: */
198: public abstract long add(long instant, long value);
199:
200: /**
201: * Subtracts a duration value (which may be negative) from the instant.
202: *
203: * @param instant the milliseconds from 1970-01-01T00:00:00Z to subtract from
204: * @param value the value to subtract, in the units of the field
205: * @return the updated milliseconds
206: * @since 1.1
207: */
208: public long subtract(long instant, int value) {
209: if (value == Integer.MIN_VALUE) {
210: return subtract(instant, (long) value);
211: }
212: return add(instant, -value);
213: }
214:
215: /**
216: * Subtracts a duration value (which may be negative) from the instant.
217: *
218: * @param instant the milliseconds from 1970-01-01T00:00:00Z to subtract from
219: * @param value the value to subtract, in the units of the field
220: * @return the updated milliseconds
221: * @since 1.1
222: */
223: public long subtract(long instant, long value) {
224: if (value == Long.MIN_VALUE) {
225: throw new ArithmeticException(
226: "Long.MIN_VALUE cannot be negated");
227: }
228: return add(instant, -value);
229: }
230:
231: /**
232: * Computes the difference between two instants, as measured in the units
233: * of this field. Any fractional units are dropped from the result. Calling
234: * getDifference reverses the effect of calling add. In the following code:
235: *
236: * <pre>
237: * long instant = ...
238: * int v = ...
239: * int age = getDifference(add(instant, v), instant);
240: * </pre>
241: *
242: * The value 'age' is the same as the value 'v'.
243: *
244: * @param minuendInstant the milliseconds from 1970-01-01T00:00:00Z to
245: * subtract from
246: * @param subtrahendInstant the milliseconds from 1970-01-01T00:00:00Z to
247: * subtract off the minuend
248: * @return the difference in the units of this field
249: */
250: public abstract int getDifference(long minuendInstant,
251: long subtrahendInstant);
252:
253: /**
254: * Computes the difference between two instants, as measured in the units
255: * of this field. Any fractional units are dropped from the result. Calling
256: * getDifference reverses the effect of calling add. In the following code:
257: *
258: * <pre>
259: * long instant = ...
260: * long v = ...
261: * long age = getDifferenceAsLong(add(instant, v), instant);
262: * </pre>
263: *
264: * The value 'age' is the same as the value 'v'.
265: *
266: * @param minuendInstant the milliseconds from 1970-01-01T00:00:00Z to
267: * subtract from
268: * @param subtrahendInstant the milliseconds from 1970-01-01T00:00:00Z to
269: * subtract off the minuend
270: * @return the difference in the units of this field
271: */
272: public abstract long getDifferenceAsLong(long minuendInstant,
273: long subtrahendInstant);
274:
275: /**
276: * Compares this duration field with another duration field for ascending
277: * unit millisecond order. This ordering is inconsistent with equals, as it
278: * ignores name and precision.
279: *
280: * @param durationField a duration field to check against
281: * @return negative value if this is less, 0 if equal, or positive value if greater
282: * @throws NullPointerException if the object is null
283: * @throws ClassCastException if the object type is not supported
284: */
285: public abstract int compareTo(Object durationField);
286:
287: /**
288: * Returns a localized unit name of this field, using the given value as an
289: * aid. For example, the unit name may differ if it is plural.
290: *
291: * @param value the duration value to use for selecting a unit name
292: * @param locale the locale to use for selecting a name, null for default
293: */
294: //String getUnitName(long value, Locale locale);
295: /**
296: * Returns a localized unit name of this field, using the given value as an
297: * aid. For example, the unit name may differ if it is plural.
298: *
299: * @param value the duration value to use for selecting a unit name
300: */
301: //String getUnitName(long value);
302: /**
303: * Get the maximum length string returned by getUnitName.
304: *
305: * @param locale the locale to use for selecting a unit name, null for
306: * default
307: * @return the maximum name length
308: */
309: //int getMaximumUnitNameLength(Locale locale);
310: //------------------------------------------------------------------------
311: /**
312: * Get a suitable debug string.
313: *
314: * @return debug string
315: */
316: public abstract String toString();
317:
318: }
|