View Javadoc

1   /*
2    *  Copyright 2001-2009 Stephen Colebourne
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   */
16  package org.joda.time;
17  
18  /**
19   * Defines the calculation engine for duration fields.
20   * The interface defines a set of methods that manipulate a millisecond duration
21   * with regards to a single field, such as months or seconds.
22   * <p>
23   * This design is extensible so, if you wish, you can extract a different field from
24   * the millisecond duration. A number of standard implementations are provided to assist.
25   *
26   * @author Stephen Colebourne
27   * @author Brian S O'Neill
28   * @since 1.0
29   */
30  public abstract class DurationField implements Comparable<DurationField> {
31  
32      /**
33       * Get the type of the field.
34       * 
35       * @return field type
36       */
37      public abstract DurationFieldType getType();
38  
39      /**
40       * Get the name of the field.
41       * <p>
42       * By convention, names are plural.
43       * 
44       * @return field name
45       */
46      public abstract String getName();
47  
48      /**
49       * Returns true if this field is supported.
50       * 
51       * @return true if this field is supported
52       */
53      public abstract boolean isSupported();
54  
55      /**
56       * Is this field precise. A precise field can calculate its value from
57       * milliseconds without needing a reference date. Put another way, a
58       * precise field's unit size is not variable.
59       * 
60       * @return true if precise
61       * @see #getUnitMillis()
62       */
63      public abstract boolean isPrecise();
64      
65      /**
66       * Returns the amount of milliseconds per unit value of this field. For
67       * example, if this field represents "seconds", then this returns the
68       * milliseconds in one second.
69       * <p>
70       * For imprecise fields, the unit size is variable, and so this method
71       * returns a suitable average value.
72       *
73       * @return the unit size of this field, in milliseconds
74       * @see #isPrecise()
75       */
76      public abstract long getUnitMillis();
77  
78      //------------------------------------------------------------------------
79      /**
80       * Get the value of this field from the milliseconds, which is approximate
81       * if this field is imprecise.
82       *
83       * @param duration  the milliseconds to query, which may be negative
84       * @return the value of the field, in the units of the field, which may be
85       * negative
86       * @throws ArithmeticException if the value is too large for an int
87       */
88      public abstract int getValue(long duration);
89  
90      /**
91       * Get the value of this field from the milliseconds, which is approximate
92       * if this field is imprecise.
93       *
94       * @param duration  the milliseconds to query, which may be negative
95       * @return the value of the field, in the units of the field, which may be
96       * negative
97       */
98      public abstract long getValueAsLong(long duration);
99  
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("Long.MIN_VALUE cannot be negated");
226         }
227         return add(instant, -value);
228     }
229 
230     /**
231      * Computes the difference between two instants, as measured in the units
232      * of this field. Any fractional units are dropped from the result. Calling
233      * getDifference reverses the effect of calling add. In the following code:
234      *
235      * <pre>
236      * long instant = ...
237      * int v = ...
238      * int age = getDifference(add(instant, v), instant);
239      * </pre>
240      *
241      * The value 'age' is the same as the value 'v'.
242      *
243      * @param minuendInstant the milliseconds from 1970-01-01T00:00:00Z to
244      * subtract from
245      * @param subtrahendInstant the milliseconds from 1970-01-01T00:00:00Z to
246      * subtract off the minuend
247      * @return the difference in the units of this field
248      */
249     public abstract int getDifference(long minuendInstant, long subtrahendInstant);
250 
251     /**
252      * Computes the difference between two instants, as measured in the units
253      * of this field. Any fractional units are dropped from the result. Calling
254      * getDifference reverses the effect of calling add. In the following code:
255      *
256      * <pre>
257      * long instant = ...
258      * long v = ...
259      * long age = getDifferenceAsLong(add(instant, v), instant);
260      * </pre>
261      *
262      * The value 'age' is the same as the value 'v'.
263      *
264      * @param minuendInstant the milliseconds from 1970-01-01T00:00:00Z to
265      * subtract from
266      * @param subtrahendInstant the milliseconds from 1970-01-01T00:00:00Z to
267      * subtract off the minuend
268      * @return the difference in the units of this field
269      */
270     public abstract long getDifferenceAsLong(long minuendInstant, long subtrahendInstant);
271 
272     // Adding this definition would be backwards incompatible with earlier subclasses
273     // This definition of compareTo was present in previous versions, and still applies
274 //    /**
275 //     * Compares this duration field with another duration field for ascending
276 //     * unit millisecond order. This ordering is inconsistent with equals, as it
277 //     * ignores name and precision.
278 //     *
279 //     * @param durationField  a duration field to check against
280 //     * @return negative value if this is less, 0 if equal, or positive value if greater
281 //     * @throws NullPointerException if the object is null
282 //     * @throws ClassCastException if the object type is not supported
283 //     */
284 //    public abstract int compareTo(DurationField durationField);
285 
286     /**
287      * Returns a localized unit name of this field, using the given value as an
288      * aid. For example, the unit name may differ if it is plural.
289      *
290      * @param value the duration value to use for selecting a unit name
291      * @param locale the locale to use for selecting a name, null for default
292      */
293     //String getUnitName(long value, Locale locale);
294 
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     /**
304      * Get the maximum length string returned by getUnitName.
305      * 
306      * @param locale the locale to use for selecting a unit name, null for
307      * default
308      * @return the maximum name length
309      */
310     //int getMaximumUnitNameLength(Locale locale);
311 
312     //------------------------------------------------------------------------
313     /**
314      * Get a suitable debug string.
315      * 
316      * @return debug string
317      */
318     public abstract String toString();
319     
320 }