EMMA Coverage Report (generated Tue Oct 28 00:01:11 GMT 2008)
[all classes][org.joda.time.field]

COVERAGE SUMMARY FOR SOURCE FILE [BaseDateTimeField.java]

nameclass, %method, %block, %line, %
BaseDateTimeField.java100% (1/1)100% (44/44)97%  (764/791)97%  (162/167)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class BaseDateTimeField100% (1/1)100% (44/44)97%  (764/791)97%  (162/167)
set (ReadablePartial, int, int [], int): int [] 100% (1/1)89%  (54/61)89%  (8/9)
add (ReadablePartial, int, int [], int): int [] 100% (1/1)94%  (163/173)94%  (32/34)
addWrapPartial (ReadablePartial, int, int [], int): int [] 100% (1/1)95%  (189/199)95%  (36/38)
BaseDateTimeField (DateTimeFieldType): void 100% (1/1)100% (13/13)100% (5/5)
add (long, int): long 100% (1/1)100% (6/6)100% (1/1)
add (long, long): long 100% (1/1)100% (6/6)100% (1/1)
addWrapField (ReadablePartial, int, int [], int): int [] 100% (1/1)100% (21/21)100% (3/3)
addWrapField (long, int): long 100% (1/1)100% (19/19)100% (3/3)
convertText (String, Locale): int 100% (1/1)100% (11/11)100% (3/3)
getAsShortText (ReadablePartial, Locale): String 100% (1/1)100% (9/9)100% (1/1)
getAsShortText (ReadablePartial, int, Locale): String 100% (1/1)100% (5/5)100% (1/1)
getAsShortText (int, Locale): String 100% (1/1)100% (5/5)100% (1/1)
getAsShortText (long): String 100% (1/1)100% (5/5)100% (1/1)
getAsShortText (long, Locale): String 100% (1/1)100% (7/7)100% (1/1)
getAsText (ReadablePartial, Locale): String 100% (1/1)100% (9/9)100% (1/1)
getAsText (ReadablePartial, int, Locale): String 100% (1/1)100% (5/5)100% (1/1)
getAsText (int, Locale): String 100% (1/1)100% (3/3)100% (1/1)
getAsText (long): String 100% (1/1)100% (5/5)100% (1/1)
getAsText (long, Locale): String 100% (1/1)100% (7/7)100% (1/1)
getDifference (long, long): int 100% (1/1)100% (6/6)100% (1/1)
getDifferenceAsLong (long, long): long 100% (1/1)100% (6/6)100% (1/1)
getLeapAmount (long): int 100% (1/1)100% (2/2)100% (1/1)
getLeapDurationField (): DurationField 100% (1/1)100% (2/2)100% (1/1)
getMaximumShortTextLength (Locale): int 100% (1/1)100% (4/4)100% (1/1)
getMaximumTextLength (Locale): int 100% (1/1)100% (24/24)100% (9/9)
getMaximumValue (ReadablePartial): int 100% (1/1)100% (3/3)100% (1/1)
getMaximumValue (ReadablePartial, int []): int 100% (1/1)100% (4/4)100% (1/1)
getMaximumValue (long): int 100% (1/1)100% (3/3)100% (1/1)
getMinimumValue (ReadablePartial): int 100% (1/1)100% (3/3)100% (1/1)
getMinimumValue (ReadablePartial, int []): int 100% (1/1)100% (4/4)100% (1/1)
getMinimumValue (long): int 100% (1/1)100% (3/3)100% (1/1)
getName (): String 100% (1/1)100% (4/4)100% (1/1)
getType (): DateTimeFieldType 100% (1/1)100% (3/3)100% (1/1)
isLeap (long): boolean 100% (1/1)100% (2/2)100% (1/1)
isSupported (): boolean 100% (1/1)100% (2/2)100% (1/1)
remainder (long): long 100% (1/1)100% (6/6)100% (1/1)
roundCeiling (long): long 100% (1/1)100% (15/15)100% (4/4)
roundHalfCeiling (long): long 100% (1/1)100% (24/24)100% (7/7)
roundHalfEven (long): long 100% (1/1)100% (38/38)100% (11/11)
roundHalfFloor (long): long 100% (1/1)100% (24/24)100% (7/7)
set (ReadablePartial, int, int [], String, Locale): int [] 100% (1/1)100% (12/12)100% (2/2)
set (long, String): long 100% (1/1)100% (6/6)100% (1/1)
set (long, String, Locale): long 100% (1/1)100% (10/10)100% (2/2)
toString (): String 100% (1/1)100% (12/12)100% (1/1)

1/*
2 *  Copyright 2001-2005 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 */
16package org.joda.time.field;
17 
18import java.util.Locale;
19 
20import org.joda.time.DateTimeField;
21import org.joda.time.DateTimeFieldType;
22import org.joda.time.DurationField;
23import org.joda.time.IllegalFieldValueException;
24import org.joda.time.ReadablePartial;
25 
26/**
27 * BaseDateTimeField provides the common behaviour for DateTimeField
28 * implementations. 
29 * <p>
30 * This class should generally not be used directly by API users. The
31 * DateTimeField class should be used when different kinds of DateTimeField
32 * objects are to be referenced.
33 * <p>
34 * BaseDateTimeField is thread-safe and immutable, and its subclasses must
35 * be as well.
36 *
37 * @author Brian S O'Neill
38 * @since 1.0
39 * @see DecoratedDateTimeField
40 */
41public abstract class BaseDateTimeField extends DateTimeField {
42 
43    /** The field type. */
44    private final DateTimeFieldType iType;
45 
46    /**
47     * Constructor.
48     */
49    protected BaseDateTimeField(DateTimeFieldType type) {
50        super();
51        if (type == null) {
52            throw new IllegalArgumentException("The type must not be null");
53        }
54        iType = type;
55    }
56    
57    public final DateTimeFieldType getType() {
58        return iType;
59    }
60 
61    public final String getName() {
62        return iType.getName();
63    }
64 
65    /**
66     * @return true always
67     */
68    public final boolean isSupported() {
69        return true;
70    }
71 
72    // Main access API
73    //------------------------------------------------------------------------
74    /**
75     * Get the value of this field from the milliseconds.
76     * 
77     * @param instant  the milliseconds from 1970-01-01T00:00:00Z to query
78     * @return the value of the field, in the units of the field
79     */
80    public abstract int get(long instant);
81 
82    //-----------------------------------------------------------------------
83    /**
84     * Get the human-readable, text value of this field from the milliseconds.
85     * If the specified locale is null, the default locale is used.
86     * <p>
87     * The default implementation returns getAsText(get(instant), locale).
88     *
89     * @param instant  the milliseconds from 1970-01-01T00:00:00Z to query
90     * @param locale the locale to use for selecting a text symbol, null means default
91     * @return the text value of the field
92     */
93    public String getAsText(long instant, Locale locale) {
94        return getAsText(get(instant), locale);
95    }
96 
97    /**
98     * Get the human-readable, text value of this field from the milliseconds.
99     * <p>
100     * The default implementation calls {@link #getAsText(long, Locale)}.
101     *
102     * @param instant  the milliseconds from 1970-01-01T00:00:00Z to query
103     * @return the text value of the field
104     */
105    public final String getAsText(long instant) {
106        return getAsText(instant, null);
107    }
108 
109    /**
110     * Get the human-readable, text value of this field from a partial instant.
111     * If the specified locale is null, the default locale is used.
112     * <p>
113     * The default implementation returns getAsText(fieldValue, locale).
114     *
115     * @param partial  the partial instant to query
116     * @param fieldValue  the field value of this field, provided for performance
117     * @param locale  the locale to use for selecting a text symbol, null for default
118     * @return the text value of the field
119     */
120    public String getAsText(ReadablePartial partial, int fieldValue, Locale locale) {
121        return getAsText(fieldValue, locale);
122    }
123 
124    /**
125     * Get the human-readable, text value of this field from a partial instant.
126     * If the specified locale is null, the default locale is used.
127     * <p>
128     * The default implementation calls {@link ReadablePartial#get(DateTimeFieldType)}
129     * and {@link #getAsText(ReadablePartial, int, Locale)}.
130     *
131     * @param partial  the partial instant to query
132     * @param locale  the locale to use for selecting a text symbol, null for default
133     * @return the text value of the field
134     */
135    public final String getAsText(ReadablePartial partial, Locale locale) {
136        return getAsText(partial, partial.get(getType()), locale);
137    }
138 
139    /**
140     * Get the human-readable, text value of this field from the field value.
141     * If the specified locale is null, the default locale is used.
142     * <p>
143     * The default implementation returns Integer.toString(get(instant)).
144     * <p>
145     * Note: subclasses that override this method should also override
146     * getMaximumTextLength.
147     *
148     * @param fieldValue  the numeric value to convert to text
149     * @param locale the locale to use for selecting a text symbol, null for default
150     * @return the text value of the field
151     */
152    public String getAsText(int fieldValue, Locale locale) {
153        return Integer.toString(fieldValue);
154    }
155 
156    //-----------------------------------------------------------------------
157    /**
158     * Get the human-readable, short text value of this field from the milliseconds.
159     * If the specified locale is null, the default locale is used.
160     * <p>
161     * The default implementation returns getAsShortText(get(instant), locale).
162     *
163     * @param instant  the milliseconds from 1970-01-01T00:00:00Z to query
164     * @param locale the locale to use for selecting a text symbol, null means default
165     * @return the text value of the field
166     */
167    public String getAsShortText(long instant, Locale locale) {
168        return getAsShortText(get(instant), locale);
169    }
170 
171    /**
172     * Get the human-readable, short text value of this field from the milliseconds.
173     * <p>
174     * The default implementation calls {@link #getAsShortText(long, Locale)}.
175     *
176     * @param instant  the milliseconds from 1970-01-01T00:00:00Z to query
177     * @return the text value of the field
178     */
179    public final String getAsShortText(long instant) {
180        return getAsShortText(instant, null);
181    }
182 
183    /**
184     * Get the human-readable, short text value of this field from a partial instant.
185     * If the specified locale is null, the default locale is used.
186     * <p>
187     * The default implementation returns getAsShortText(fieldValue, locale).
188     *
189     * @param partial  the partial instant to query
190     * @param fieldValue  the field value of this field, provided for performance
191     * @param locale  the locale to use for selecting a text symbol, null for default
192     * @return the text value of the field
193     */
194    public String getAsShortText(ReadablePartial partial, int fieldValue, Locale locale) {
195        return getAsShortText(fieldValue, locale);
196    }
197 
198    /**
199     * Get the human-readable, short text value of this field from a partial instant.
200     * If the specified locale is null, the default locale is used.
201     * <p>
202     * The default implementation calls {@link ReadablePartial#get(DateTimeFieldType)}
203     * and {@link #getAsText(ReadablePartial, int, Locale)}.
204     *
205     * @param partial  the partial instant to query
206     * @param locale  the locale to use for selecting a text symbol, null for default
207     * @return the text value of the field
208     */
209    public final String getAsShortText(ReadablePartial partial, Locale locale) {
210        return getAsShortText(partial, partial.get(getType()), locale);
211    }
212 
213    /**
214     * Get the human-readable, short text value of this field from the field value.
215     * If the specified locale is null, the default locale is used.
216     * <p>
217     * The default implementation returns getAsText(fieldValue, locale).
218     * <p>
219     * Note: subclasses that override this method should also override
220     * getMaximumShortTextLength.
221     *
222     * @param fieldValue  the numeric value to convert to text
223     * @param locale the locale to use for selecting a text symbol, null for default
224     * @return the text value of the field
225     */
226    public String getAsShortText(int fieldValue, Locale locale) {
227        return getAsText(fieldValue, locale);
228    }
229 
230    //-----------------------------------------------------------------------
231    /**
232     * Adds a value (which may be negative) to the instant value,
233     * overflowing into larger fields if necessary.
234     * <p>
235     * The value will be added to this field. If the value is too large to be
236     * added solely to this field, larger fields will increase as required.
237     * Smaller fields should be unaffected, except where the result would be
238     * an invalid value for a smaller field. In this case the smaller field is
239     * adjusted to be in range.
240     * <p>
241     * For example, in the ISO chronology:<br>
242     * 2000-08-20 add six months is 2001-02-20<br>
243     * 2000-08-20 add twenty months is 2002-04-20<br>
244     * 2000-08-20 add minus nine months is 1999-11-20<br>
245     * 2001-01-31 add one month  is 2001-02-28<br>
246     * 2001-01-31 add two months is 2001-03-31<br>
247     * 
248     * @param instant  the milliseconds from 1970-01-01T00:00:00Z to add to
249     * @param value  the value to add, in the units of the field
250     * @return the updated milliseconds
251     */
252    public long add(long instant, int value) {
253        return getDurationField().add(instant, value);
254    }
255 
256    /**
257     * Adds a value (which may be negative) to the instant value,
258     * overflowing into larger fields if necessary.
259     * 
260     * @param instant  the milliseconds from 1970-01-01T00:00:00Z to add to
261     * @param value  the long value to add, in the units of the field
262     * @return the updated milliseconds
263     * @throws IllegalArgumentException if value is too large
264     * @see #add(long,int)
265     */
266    public long add(long instant, long value) {
267        return getDurationField().add(instant, value);
268    }
269 
270    /**
271     * Adds a value (which may be negative) to the partial instant,
272     * throwing an exception if the maximum size of the instant is reached.
273     * <p>
274     * The value will be added to this field, overflowing into larger fields
275     * if necessary. Smaller fields should be unaffected, except where the
276     * result would be an invalid value for a smaller field. In this case the
277     * smaller field is adjusted to be in range.
278     * <p>
279     * Partial instants only contain some fields. This may result in a maximum
280     * possible value, such as TimeOfDay being limited to 23:59:59:999. If this
281     * limit is breached by the add an exception is thrown.
282     * <p>
283     * For example, in the ISO chronology:<br>
284     * 2000-08-20 add six months is 2000-02-20<br>
285     * 2000-08-20 add twenty months is 2000-04-20<br>
286     * 2000-08-20 add minus nine months is 2000-11-20<br>
287     * 2001-01-31 add one month  is 2001-02-28<br>
288     * 2001-01-31 add two months is 2001-03-31<br>
289     * 
290     * @param instant  the partial instant
291     * @param fieldIndex  the index of this field in the partial
292     * @param values  the values of the partial instant which should be updated
293     * @param valueToAdd  the value to add, in the units of the field
294     * @return the passed in values
295     * @throws IllegalArgumentException if the value is invalid or the maximum instant is reached
296     */
297    public int[] add(ReadablePartial instant, int fieldIndex, int[] values, int valueToAdd) {
298        if (valueToAdd == 0) {
299            return values;
300        }
301        // there are more efficient algorithms than this (especially for time only fields)
302        // trouble is when dealing with days and months, so we use this technique of
303        // adding/removing one from the larger field at a time
304        DateTimeField nextField = null;
305        
306        while (valueToAdd > 0) {
307            int max = getMaximumValue(instant, values);
308            long proposed = values[fieldIndex] + valueToAdd;
309            if (proposed <= max) {
310                values[fieldIndex] = (int) proposed;
311                break;
312            }
313            if (nextField == null) {
314                if (fieldIndex == 0) {
315                    throw new IllegalArgumentException("Maximum value exceeded for add");
316                }
317                nextField = instant.getField(fieldIndex - 1);
318                // test only works if this field is UTC (ie. local)
319                if (getRangeDurationField().getType() != nextField.getDurationField().getType()) {
320                    throw new IllegalArgumentException("Fields invalid for add");
321                }
322            }
323            valueToAdd -= (max + 1) - values[fieldIndex];  // reduce the amount to add
324            values = nextField.add(instant, fieldIndex - 1, values, 1);  // add 1 to next bigger field
325            values[fieldIndex] = getMinimumValue(instant, values);  // reset this field to zero
326        }
327        while (valueToAdd < 0) {
328            int min = getMinimumValue(instant, values);
329            long proposed = values[fieldIndex] + valueToAdd;
330            if (proposed >= min) {
331                values[fieldIndex] = (int) proposed;
332                break;
333            }
334            if (nextField == null) {
335                if (fieldIndex == 0) {
336                    throw new IllegalArgumentException("Maximum value exceeded for add");
337                }
338                nextField = instant.getField(fieldIndex - 1);
339                if (getRangeDurationField().getType() != nextField.getDurationField().getType()) {
340                    throw new IllegalArgumentException("Fields invalid for add");
341                }
342            }
343            valueToAdd -= (min - 1) - values[fieldIndex];  // reduce the amount to add
344            values = nextField.add(instant, fieldIndex - 1, values, -1);  // subtract 1 from next bigger field
345            values[fieldIndex] = getMaximumValue(instant, values);  // reset this field to max value
346        }
347        
348        return set(instant, fieldIndex, values, values[fieldIndex]);  // adjusts smaller fields
349    }
350 
351    /**
352     * Adds a value (which may be negative) to the partial instant,
353     * wrapping the whole partial if the maximum size of the partial is reached.
354     * <p>
355     * The value will be added to this field, overflowing into larger fields
356     * if necessary. Smaller fields should be unaffected, except where the
357     * result would be an invalid value for a smaller field. In this case the
358     * smaller field is adjusted to be in range.
359     * <p>
360     * Partial instants only contain some fields. This may result in a maximum
361     * possible value, such as TimeOfDay normally being limited to 23:59:59:999.
362     * If ths limit is reached by the addition, this method will wrap back to
363     * 00:00:00.000. In fact, you would generally only use this method for
364     * classes that have a limitation such as this.
365     * <p>
366     * For example, in the ISO chronology:<br>
367     * 10:20:30 add 20 minutes is 10:40:30<br>
368     * 10:20:30 add 45 minutes is 11:05:30<br>
369     * 10:20:30 add 16 hours is 02:20:30<br>
370     * 
371     * @param instant  the partial instant
372     * @param fieldIndex  the index of this field in the partial
373     * @param values  the values of the partial instant which should be updated
374     * @param valueToAdd  the value to add, in the units of the field
375     * @return the passed in values
376     * @throws IllegalArgumentException if the value is invalid or the maximum instant is reached
377     */
378    public int[] addWrapPartial(ReadablePartial instant, int fieldIndex, int[] values, int valueToAdd) {
379        if (valueToAdd == 0) {
380            return values;
381        }
382        // there are more efficient algorithms than this (especially for time only fields)
383        // trouble is when dealing with days and months, so we use this technique of
384        // adding/removing one from the larger field at a time
385        DateTimeField nextField = null;
386        
387        while (valueToAdd > 0) {
388            int max = getMaximumValue(instant, values);
389            long proposed = values[fieldIndex] + valueToAdd;
390            if (proposed <= max) {
391                values[fieldIndex] = (int) proposed;
392                break;
393            }
394            if (nextField == null) {
395                if (fieldIndex == 0) {
396                    valueToAdd -= (max + 1) - values[fieldIndex];
397                    values[fieldIndex] = getMinimumValue(instant, values);
398                    continue;
399                }
400                nextField = instant.getField(fieldIndex - 1);
401                // test only works if this field is UTC (ie. local)
402                if (getRangeDurationField().getType() != nextField.getDurationField().getType()) {
403                    throw new IllegalArgumentException("Fields invalid for add");
404                }
405            }
406            valueToAdd -= (max + 1) - values[fieldIndex];  // reduce the amount to add
407            values = nextField.addWrapPartial(instant, fieldIndex - 1, values, 1);  // add 1 to next bigger field
408            values[fieldIndex] = getMinimumValue(instant, values);  // reset this field to zero
409        }
410        while (valueToAdd < 0) {
411            int min = getMinimumValue(instant, values);
412            long proposed = values[fieldIndex] + valueToAdd;
413            if (proposed >= min) {
414                values[fieldIndex] = (int) proposed;
415                break;
416            }
417            if (nextField == null) {
418                if (fieldIndex == 0) {
419                    valueToAdd -= (min - 1) - values[fieldIndex];
420                    values[fieldIndex] = getMaximumValue(instant, values);
421                    continue;
422                }
423                nextField = instant.getField(fieldIndex - 1);
424                if (getRangeDurationField().getType() != nextField.getDurationField().getType()) {
425                    throw new IllegalArgumentException("Fields invalid for add");
426                }
427            }
428            valueToAdd -= (min - 1) - values[fieldIndex];  // reduce the amount to add
429            values = nextField.addWrapPartial(instant, fieldIndex - 1, values, -1);  // subtract 1 from next bigger field
430            values[fieldIndex] = getMaximumValue(instant, values);  // reset this field to max value
431        }
432        
433        return set(instant, fieldIndex, values, values[fieldIndex]);  // adjusts smaller fields
434    }
435 
436    /**
437     * Adds a value (which may be negative) to the instant value,
438     * wrapping within this field.
439     * <p>
440     * The value will be added to this field. If the value is too large to be
441     * added solely to this field then it wraps. Larger fields are always
442     * unaffected. Smaller fields should be unaffected, except where the
443     * result would be an invalid value for a smaller field. In this case the
444     * smaller field is adjusted to be in range.
445     * <p>
446     * For example, in the ISO chronology:<br>
447     * 2000-08-20 addWrapField six months is 2000-02-20<br>
448     * 2000-08-20 addWrapField twenty months is 2000-04-20<br>
449     * 2000-08-20 addWrapField minus nine months is 2000-11-20<br>
450     * 2001-01-31 addWrapField one month  is 2001-02-28<br>
451     * 2001-01-31 addWrapField two months is 2001-03-31<br>
452     * <p>
453     * The default implementation internally calls set. Subclasses are
454     * encouraged to provide a more efficient implementation.
455     * 
456     * @param instant  the milliseconds from 1970-01-01T00:00:00Z to add to
457     * @param value  the value to add, in the units of the field
458     * @return the updated milliseconds
459     */
460    public long addWrapField(long instant, int value) {
461        int current = get(instant);
462        int wrapped = FieldUtils.getWrappedValue
463            (current, value, getMinimumValue(instant), getMaximumValue(instant));
464        return set(instant, wrapped);
465    }
466 
467    /**
468     * Adds a value (which may be negative) to the partial instant,
469     * wrapping within this field.
470     * <p>
471     * The value will be added to this field. If the value is too large to be
472     * added solely to this field then it wraps. Larger fields are always
473     * unaffected. Smaller fields should be unaffected, except where the
474     * result would be an invalid value for a smaller field. In this case the
475     * smaller field is adjusted to be in range.
476     * <p>
477     * For example, in the ISO chronology:<br>
478     * 2000-08-20 addWrapField six months is 2000-02-20<br>
479     * 2000-08-20 addWrapField twenty months is 2000-04-20<br>
480     * 2000-08-20 addWrapField minus nine months is 2000-11-20<br>
481     * 2001-01-31 addWrapField one month  is 2001-02-28<br>
482     * 2001-01-31 addWrapField two months is 2001-03-31<br>
483     * <p>
484     * The default implementation internally calls set. Subclasses are
485     * encouraged to provide a more efficient implementation.
486     * 
487     * @param instant  the partial instant
488     * @param fieldIndex  the index of this field in the instant
489     * @param values  the values of the partial instant which should be updated
490     * @param valueToAdd  the value to add, in the units of the field
491     * @return the passed in values
492     * @throws IllegalArgumentException if the value is invalid
493     */
494    public int[] addWrapField(ReadablePartial instant, int fieldIndex, int[] values, int valueToAdd) {
495        int current = values[fieldIndex];
496        int wrapped = FieldUtils.getWrappedValue
497            (current, valueToAdd, getMinimumValue(instant), getMaximumValue(instant));
498        return set(instant, fieldIndex, values, wrapped);  // adjusts smaller fields
499    }
500 
501    //-----------------------------------------------------------------------
502    /**
503     * Computes the difference between two instants, as measured in the units
504     * of this field. Any fractional units are dropped from the result. Calling
505     * getDifference reverses the effect of calling add. In the following code:
506     *
507     * <pre>
508     * long instant = ...
509     * int v = ...
510     * int age = getDifference(add(instant, v), instant);
511     * </pre>
512     *
513     * The value 'age' is the same as the value 'v'.
514     *
515     * @param minuendInstant the milliseconds from 1970-01-01T00:00:00Z to
516     * subtract from
517     * @param subtrahendInstant the milliseconds from 1970-01-01T00:00:00Z to
518     * subtract off the minuend
519     * @return the difference in the units of this field
520     */
521    public int getDifference(long minuendInstant, long subtrahendInstant) {
522        return getDurationField().getDifference(minuendInstant, subtrahendInstant);
523    }
524 
525    /**
526     * Computes the difference between two instants, as measured in the units
527     * of this field. Any fractional units are dropped from the result. Calling
528     * getDifference reverses the effect of calling add. In the following code:
529     *
530     * <pre>
531     * long instant = ...
532     * long v = ...
533     * long age = getDifferenceAsLong(add(instant, v), instant);
534     * </pre>
535     *
536     * The value 'age' is the same as the value 'v'.
537     *
538     * @param minuendInstant the milliseconds from 1970-01-01T00:00:00Z to
539     * subtract from
540     * @param subtrahendInstant the milliseconds from 1970-01-01T00:00:00Z to
541     * subtract off the minuend
542     * @return the difference in the units of this field
543     */
544    public long getDifferenceAsLong(long minuendInstant, long subtrahendInstant) {
545        return getDurationField().getDifferenceAsLong(minuendInstant, subtrahendInstant);
546    }
547 
548    /**
549     * Sets a value in the milliseconds supplied.
550     * <p>
551     * The value of this field will be set.
552     * If the value is invalid, an exception if thrown.
553     * <p>
554     * If setting this field would make other fields invalid, then those fields
555     * may be changed. For example if the current date is the 31st January, and
556     * the month is set to February, the day would be invalid. Instead, the day
557     * would be changed to the closest value - the 28th/29th February as appropriate.
558     * 
559     * @param instant  the milliseconds from 1970-01-01T00:00:00Z to set in
560     * @param value  the value to set, in the units of the field
561     * @return the updated milliseconds
562     * @throws IllegalArgumentException if the value is invalid
563     */
564    public abstract long set(long instant, int value);
565 
566    /**
567     * Sets a value using the specified partial instant.
568     * <p>
569     * The value of this field (specified by the index) will be set.
570     * If the value is invalid, an exception if thrown.
571     * <p>
572     * If setting this field would make other fields invalid, then those fields
573     * may be changed. For example if the current date is the 31st January, and
574     * the month is set to February, the day would be invalid. Instead, the day
575     * would be changed to the closest value - the 28th/29th February as appropriate.
576     * 
577     * @param partial  the partial instant
578     * @param fieldIndex  the index of this field in the instant
579     * @param values  the values to update
580     * @param newValue  the value to set, in the units of the field
581     * @return the updated values
582     * @throws IllegalArgumentException if the value is invalid
583     */
584    public int[] set(ReadablePartial partial, int fieldIndex, int[] values, int newValue) {
585        FieldUtils.verifyValueBounds(this, newValue, getMinimumValue(partial, values), getMaximumValue(partial, values));
586        values[fieldIndex] = newValue;
587        
588        // may need to adjust smaller fields
589        for (int i = fieldIndex + 1; i < partial.size(); i++) {
590            DateTimeField field = partial.getField(i);
591            if (values[i] > field.getMaximumValue(partial, values)) {
592                values[i] = field.getMaximumValue(partial, values);
593            }
594            if (values[i] < field.getMinimumValue(partial, values)) {
595                values[i] = field.getMinimumValue(partial, values);
596            }
597        }
598        return values;
599    }
600 
601    /**
602     * Sets a value in the milliseconds supplied from a human-readable, text value.
603     * If the specified locale is null, the default locale is used.
604     * <p>
605     * This implementation uses <code>convertText(String, Locale)</code> and
606     * {@link #set(long, int)}.
607     * <p>
608     * Note: subclasses that override this method should also override
609     * getAsText.
610     *
611     * @param instant  the milliseconds from 1970-01-01T00:00:00Z to set in
612     * @param text  the text value to set
613     * @param locale the locale to use for selecting a text symbol, null for default
614     * @return the updated milliseconds
615     * @throws IllegalArgumentException if the text value is invalid
616     */
617    public long set(long instant, String text, Locale locale) {
618        int value = convertText(text, locale);
619        return set(instant, value);
620    }
621 
622    /**
623     * Sets a value in the milliseconds supplied from a human-readable, text value.
624     * <p>
625     * This implementation uses {@link #set(long, String, Locale)}.
626     * <p>
627     * Note: subclasses that override this method should also override getAsText.
628     *
629     * @param instant  the milliseconds from 1970-01-01T00:00:00Z to set in
630     * @param text  the text value to set
631     * @return the updated milliseconds
632     * @throws IllegalArgumentException if the text value is invalid
633     */
634    public final long set(long instant, String text) {
635        return set(instant, text, null);
636    }
637 
638    /**
639     * Sets a value in the milliseconds supplied from a human-readable, text value.
640     * If the specified locale is null, the default locale is used.
641     * <p>
642     * This implementation uses <code>convertText(String, Locale)</code> and
643     * {@link #set(ReadablePartial, int, int[], int)}.
644     *
645     * @param instant  the partial instant
646     * @param fieldIndex  the index of this field in the instant
647     * @param values  the values of the partial instant which should be updated
648     * @param text  the text value to set
649     * @param locale the locale to use for selecting a text symbol, null for default
650     * @return the passed in values
651     * @throws IllegalArgumentException if the text value is invalid
652     */
653    public int[] set(ReadablePartial instant, int fieldIndex, int[] values, String text, Locale locale) {
654        int value = convertText(text, locale);
655        return set(instant, fieldIndex, values, value);
656    }
657 
658    /**
659     * Convert the specified text and locale into a value.
660     * 
661     * @param text  the text to convert
662     * @param locale  the locale to convert using
663     * @return the value extracted from the text
664     * @throws IllegalArgumentException if the text is invalid
665     */
666    protected int convertText(String text, Locale locale) {
667        try {
668            return Integer.parseInt(text);
669        } catch (NumberFormatException ex) {
670            throw new IllegalFieldValueException(getType(), text);
671        }
672    }
673 
674    // Extra information API
675    //------------------------------------------------------------------------
676    /**
677     * Returns the duration per unit value of this field. For example, if this
678     * field represents "hour of day", then the unit duration is an hour.
679     *
680     * @return the duration of this field, or UnsupportedDurationField if field
681     * has no duration
682     */
683    public abstract DurationField getDurationField();
684 
685    /**
686     * Returns the range duration of this field. For example, if this field
687     * represents "hour of day", then the range duration is a day.
688     *
689     * @return the range duration of this field, or null if field has no range
690     */
691    public abstract DurationField getRangeDurationField();
692 
693    /**
694     * Returns whether this field is 'leap' for the specified instant.
695     * <p>
696     * For example, a leap year would return true, a non leap year would return
697     * false.
698     * <p>
699     * This implementation returns false.
700     * 
701     * @return true if the field is 'leap'
702     */
703    public boolean isLeap(long instant) {
704        return false;
705    }
706 
707    /**
708     * Gets the amount by which this field is 'leap' for the specified instant.
709     * <p>
710     * For example, a leap year would return one, a non leap year would return
711     * zero.
712     * <p>
713     * This implementation returns zero.
714     */
715    public int getLeapAmount(long instant) {
716        return 0;
717    }
718 
719    /**
720     * If this field were to leap, then it would be in units described by the
721     * returned duration. If this field doesn't ever leap, null is returned.
722     * <p>
723     * This implementation returns null.
724     */
725    public DurationField getLeapDurationField() {
726        return null;
727    }
728 
729    /**
730     * Get the minimum allowable value for this field.
731     * 
732     * @return the minimum valid value for this field, in the units of the
733     * field
734     */
735    public abstract int getMinimumValue();
736 
737    /**
738     * Get the minimum value for this field evaluated at the specified time.
739     * <p>
740     * This implementation returns the same as {@link #getMinimumValue()}.
741     * 
742     * @param instant  the milliseconds from 1970-01-01T00:00:00Z to query
743     * @return the minimum value for this field, in the units of the field
744     */
745    public int getMinimumValue(long instant) {
746        return getMinimumValue();
747    }
748 
749    /**
750     * Get the minimum value for this field evaluated at the specified instant.
751     * <p>
752     * This implementation returns the same as {@link #getMinimumValue()}.
753     * 
754     * @param instant  the partial instant to query
755     * @return the minimum value for this field, in the units of the field
756     */
757    public int getMinimumValue(ReadablePartial instant) {
758        return getMinimumValue();
759    }
760 
761    /**
762     * Get the minimum value for this field using the partial instant and
763     * the specified values.
764     * <p>
765     * This implementation returns the same as {@link #getMinimumValue(ReadablePartial)}.
766     * 
767     * @param instant  the partial instant to query
768     * @param values  the values to use
769     * @return the minimum value for this field, in the units of the field
770     */
771    public int getMinimumValue(ReadablePartial instant, int[] values) {
772        return getMinimumValue(instant);
773    }
774 
775    /**
776     * Get the maximum allowable value for this field.
777     * 
778     * @return the maximum valid value for this field, in the units of the
779     * field
780     */
781    public abstract int getMaximumValue();
782 
783    /**
784     * Get the maximum value for this field evaluated at the specified time.
785     * <p>
786     * This implementation returns the same as {@link #getMaximumValue()}.
787     * 
788     * @param instant  the milliseconds from 1970-01-01T00:00:00Z to query
789     * @return the maximum value for this field, in the units of the field
790     */
791    public int getMaximumValue(long instant) {
792        return getMaximumValue();
793    }
794 
795    /**
796     * Get the maximum value for this field evaluated at the specified instant.
797     * <p>
798     * This implementation returns the same as {@link #getMaximumValue()}.
799     * 
800     * @param instant  the partial instant to query
801     * @return the maximum value for this field, in the units of the field
802     */
803    public int getMaximumValue(ReadablePartial instant) {
804        return getMaximumValue();
805    }
806 
807    /**
808     * Get the maximum value for this field using the partial instant and
809     * the specified values.
810     * <p>
811     * This implementation returns the same as {@link #getMaximumValue(ReadablePartial)}.
812     * 
813     * @param instant  the partial instant to query
814     * @param values  the values to use
815     * @return the maximum value for this field, in the units of the field
816     */
817    public int getMaximumValue(ReadablePartial instant, int[] values) {
818        return getMaximumValue(instant);
819    }
820 
821    /**
822     * Get the maximum text value for this field. The default implementation
823     * returns the equivalent of Integer.toString(getMaximumValue()).length().
824     * 
825     * @param locale  the locale to use for selecting a text symbol
826     * @return the maximum text length
827     */
828    public int getMaximumTextLength(Locale locale) {
829        int max = getMaximumValue();
830        if (max >= 0) {
831            if (max < 10) {
832                return 1;
833            } else if (max < 100) {
834                return 2;
835            } else if (max < 1000) {
836                return 3;
837            }
838        }
839        return Integer.toString(max).length();
840    }
841 
842    /**
843     * Get the maximum short text value for this field. The default
844     * implementation returns getMaximumTextLength().
845     * 
846     * @param locale  the locale to use for selecting a text symbol
847     * @return the maximum short text length
848     */
849    public int getMaximumShortTextLength(Locale locale) {
850        return getMaximumTextLength(locale);
851    }
852 
853    // Calculation API
854    //------------------------------------------------------------------------
855    /**
856     * Round to the lowest whole unit of this field. After rounding, the value
857     * of this field and all fields of a higher magnitude are retained. The
858     * fractional millis that cannot be expressed in whole increments of this
859     * field are set to minimum.
860     * <p>
861     * For example, a datetime of 2002-11-02T23:34:56.789, rounded to the
862     * lowest whole hour is 2002-11-02T23:00:00.000.
863     *
864     * @param instant  the milliseconds from 1970-01-01T00:00:00Z to round
865     * @return rounded milliseconds
866     */
867    public abstract long roundFloor(long instant);
868 
869    /**
870     * Round to the highest whole unit of this field. The value of this field
871     * and all fields of a higher magnitude may be incremented in order to
872     * achieve this result. The fractional millis that cannot be expressed in
873     * whole increments of this field are set to minimum.
874     * <p>
875     * For example, a datetime of 2002-11-02T23:34:56.789, rounded to the
876     * highest whole hour is 2002-11-03T00:00:00.000.
877     * <p>
878     * The default implementation calls roundFloor, and if the instant is
879     * modified as a result, adds one field unit. Subclasses are encouraged to
880     * provide a more efficient implementation.
881     *
882     * @param instant  the milliseconds from 1970-01-01T00:00:00Z to round
883     * @return rounded milliseconds
884     */
885    public long roundCeiling(long instant) {
886        long newInstant = roundFloor(instant);
887        if (newInstant != instant) {
888            instant = add(newInstant, 1);
889        }
890        return instant;
891    }
892 
893    /**
894     * Round to the nearest whole unit of this field. If the given millisecond
895     * value is closer to the floor or is exactly halfway, this function
896     * behaves like roundFloor. If the millisecond value is closer to the
897     * ceiling, this function behaves like roundCeiling.
898     *
899     * @param instant  the milliseconds from 1970-01-01T00:00:00Z to round
900     * @return rounded milliseconds
901     */
902    public long roundHalfFloor(long instant) {
903        long floor = roundFloor(instant);
904        long ceiling = roundCeiling(instant);
905 
906        long diffFromFloor = instant - floor;
907        long diffToCeiling = ceiling - instant;
908 
909        if (diffFromFloor <= diffToCeiling) {
910            // Closer to the floor, or halfway - round floor
911            return floor;
912        } else {
913            return ceiling;
914        }
915    }
916 
917    /**
918     * Round to the nearest whole unit of this field. If the given millisecond
919     * value is closer to the floor, this function behaves like roundFloor. If
920     * the millisecond value is closer to the ceiling or is exactly halfway,
921     * this function behaves like roundCeiling.
922     *
923     * @param instant  the milliseconds from 1970-01-01T00:00:00Z to round
924     * @return rounded milliseconds
925     */
926    public long roundHalfCeiling(long instant) {
927        long floor = roundFloor(instant);
928        long ceiling = roundCeiling(instant);
929 
930        long diffFromFloor = instant - floor;
931        long diffToCeiling = ceiling - instant;
932 
933        if (diffToCeiling <= diffFromFloor) {
934            // Closer to the ceiling, or halfway - round ceiling
935            return ceiling;
936        } else {
937            return floor;
938        }
939    }
940 
941    /**
942     * Round to the nearest whole unit of this field. If the given millisecond
943     * value is closer to the floor, this function behaves like roundFloor. If
944     * the millisecond value is closer to the ceiling, this function behaves
945     * like roundCeiling.
946     * <p>
947     * If the millisecond value is exactly halfway between the floor and
948     * ceiling, the ceiling is chosen over the floor only if it makes this
949     * field's value even.
950     *
951     * @param instant  the milliseconds from 1970-01-01T00:00:00Z to round
952     * @return rounded milliseconds
953     */
954    public long roundHalfEven(long instant) {
955        long floor = roundFloor(instant);
956        long ceiling = roundCeiling(instant);
957 
958        long diffFromFloor = instant - floor;
959        long diffToCeiling = ceiling - instant;
960 
961        if (diffFromFloor < diffToCeiling) {
962            // Closer to the floor - round floor
963            return floor;
964        } else if (diffToCeiling < diffFromFloor) {
965            // Closer to the ceiling - round ceiling
966            return ceiling;
967        } else {
968            // Round to the instant that makes this field even. If both values
969            // make this field even (unlikely), favor the ceiling.
970            if ((get(ceiling) & 1) == 0) {
971                return ceiling;
972            }
973            return floor;
974        }
975    }
976 
977    /**
978     * Returns the fractional duration milliseconds of this field. In other
979     * words, calling remainder returns the duration that roundFloor would
980     * subtract.
981     * <p>
982     * For example, on a datetime of 2002-11-02T23:34:56.789, the remainder by
983     * hour is 34 minutes and 56.789 seconds.
984     * <p>
985     * The default implementation computes
986     * <code>instant - roundFloor(instant)</code>. Subclasses are encouraged to
987     * provide a more efficient implementation.
988     *
989     * @param instant the milliseconds from 1970-01-01T00:00:00Z to get the
990     * remainder
991     * @return remainder duration, in milliseconds
992     */
993    public long remainder(long instant) {
994        return instant - roundFloor(instant);
995    }
996 
997    /**
998     * Get a suitable debug string.
999     * 
1000     * @return debug string
1001     */
1002    public String toString() {
1003        return "DateTimeField[" + getName() + ']';
1004    }
1005 
1006}

[all classes][org.joda.time.field]
EMMA 2.0.5312 (C) Vladimir Roubtsov