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.field;
17  
18  import java.io.Serializable;
19  
20  import org.joda.time.DurationField;
21  import org.joda.time.DurationFieldType;
22  
23  /**
24   * BaseDurationField provides the common behaviour for DurationField
25   * implementations.
26   * <p>
27   * This class should generally not be used directly by API users. The
28   * DurationField class should be used when different kinds of DurationField
29   * objects are to be referenced.
30   * <p>
31   * BaseDurationField is thread-safe and immutable, and its subclasses must
32   * be as well.
33   *
34   * @author Brian S O'Neill
35   * @see DecoratedDurationField
36   * @since 1.0
37   */
38  public abstract class BaseDurationField extends DurationField implements Serializable {
39  
40      /** Serialization lock. */
41      private static final long serialVersionUID = -2554245107589433218L;
42  
43      /** A desriptive name for the field. */
44      private final DurationFieldType iType;
45  
46      protected BaseDurationField(DurationFieldType type) {
47          super();
48          if (type == null) {
49              throw new IllegalArgumentException("The type must not be null");
50          }
51          iType = type;
52      }
53  
54      public final DurationFieldType getType() {
55          return iType;
56      }
57  
58      public final String getName() {
59          return iType.getName();
60      }
61  
62      /**
63       * @return true always
64       */
65      public final boolean isSupported() {
66          return true;
67      }
68  
69      //------------------------------------------------------------------------
70      /**
71       * Get the value of this field from the milliseconds, which is approximate
72       * if this field is imprecise.
73       *
74       * @param duration  the milliseconds to query, which may be negative
75       * @return the value of the field, in the units of the field, which may be
76       * negative
77       */
78      public int getValue(long duration) {
79          return FieldUtils.safeToInt(getValueAsLong(duration));
80      }
81  
82      /**
83       * Get the value of this field from the milliseconds, which is approximate
84       * if this field is imprecise.
85       *
86       * @param duration  the milliseconds to query, which may be negative
87       * @return the value of the field, in the units of the field, which may be
88       * negative
89       */
90      public long getValueAsLong(long duration) {
91          return duration / getUnitMillis();
92      }
93  
94      /**
95       * Get the value of this field from the milliseconds relative to an
96       * instant.
97       *
98       * <p>If the milliseconds is positive, then the instant is treated as a
99       * "start instant". If negative, the instant is treated as an "end
100      * instant".
101      *
102      * <p>The default implementation returns
103      * <code>Utils.safeToInt(getAsLong(millisDuration, instant))</code>.
104      * 
105      * @param duration  the milliseconds to query, which may be negative
106      * @param instant  the start instant to calculate relative to
107      * @return the value of the field, in the units of the field, which may be
108      * negative
109      */
110     public int getValue(long duration, long instant) {
111         return FieldUtils.safeToInt(getValueAsLong(duration, instant));
112     }
113 
114     /**
115      * Get the millisecond duration of this field from its value, which is
116      * approximate if this field is imprecise.
117      * 
118      * @param value  the value of the field, which may be negative
119      * @return the milliseconds that the field represents, which may be
120      * negative
121      */
122     public long getMillis(int value) {
123         return value * getUnitMillis();  // safe
124     }
125 
126     /**
127      * Get the millisecond duration of this field from its value, which is
128      * approximate if this field is imprecise.
129      * 
130      * @param value  the value of the field, which may be negative
131      * @return the milliseconds that the field represents, which may be
132      * negative
133      */
134     public long getMillis(long value) {
135         return FieldUtils.safeMultiply(value, getUnitMillis());
136     }
137 
138     // Calculation API
139     //------------------------------------------------------------------------
140     public int getDifference(long minuendInstant, long subtrahendInstant) {
141         return FieldUtils.safeToInt(getDifferenceAsLong(minuendInstant, subtrahendInstant));
142     }
143 
144     //------------------------------------------------------------------------
145     public int compareTo(DurationField otherField) {
146         long otherMillis = otherField.getUnitMillis();
147         long thisMillis = getUnitMillis();
148         // cannot do (thisMillis - otherMillis) as can overflow
149         if (thisMillis == otherMillis) {
150             return 0;
151         }
152         if (thisMillis < otherMillis) {
153             return -1;
154         } else {
155             return 1;
156         }
157     }
158 
159     /**
160      * Get a suitable debug string.
161      * 
162      * @return debug string
163      */
164     public String toString() {
165         return "DurationField[" + getName() + ']';
166     }
167 
168 }