KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > joda > time > field > DividedDateTimeField


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  */

16 package org.joda.time.field;
17
18 import org.joda.time.DateTimeField;
19 import org.joda.time.DateTimeFieldType;
20 import org.joda.time.DurationField;
21
22 /**
23  * Divides a DateTimeField such that the retrieved values are reduced by a
24  * fixed divisor. The field's unit duration is scaled accordingly, but the
25  * range duration is unchanged.
26  * <p>
27  * DividedDateTimeField is thread-safe and immutable.
28  *
29  * @see RemainderDateTimeField
30  *
31  * @author Stephen Colebourne
32  * @author Brian S O'Neill
33  * @since 1.0
34  */

35 public class DividedDateTimeField extends DecoratedDateTimeField {
36
37     private static final long serialVersionUID = 8318475124230605365L;
38
39     // Shared with RemainderDateTimeField.
40
final int iDivisor;
41     final DurationField iDurationField;
42
43     private final int iMin;
44     private final int iMax;
45
46     /**
47      * Constructor.
48      *
49      * @param field the field to wrap, like "year()".
50      * @param type the field type this field will actually use
51      * @param divisor divisor, such as 100 years in a century
52      * @throws IllegalArgumentException if divisor is less than two
53      */

54     public DividedDateTimeField(DateTimeField field,
55                                 DateTimeFieldType type, int divisor) {
56         super(field, type);
57                 
58         if (divisor < 2) {
59             throw new IllegalArgumentException JavaDoc("The divisor must be at least 2");
60         }
61
62         DurationField unitField = field.getDurationField();
63         if (unitField == null) {
64             iDurationField = null;
65         } else {
66             iDurationField = new ScaledDurationField(
67                 unitField, type.getDurationType(), divisor);
68         }
69
70         iDivisor = divisor;
71
72         int i = field.getMinimumValue();
73         int min = (i >= 0) ? i / divisor : ((i + 1) / divisor - 1);
74
75         int j = field.getMaximumValue();
76         int max = (j >= 0) ? j / divisor : ((j + 1) / divisor - 1);
77
78         iMin = min;
79         iMax = max;
80     }
81
82     /**
83      * Construct a DividedDateTimeField that compliments the given
84      * RemainderDateTimeField.
85      *
86      * @param remainderField complimentary remainder field, like "yearOfCentury()".
87      * @param type the field type this field will actually use
88      */

89     public DividedDateTimeField(RemainderDateTimeField remainderField, DateTimeFieldType type) {
90         super(remainderField.getWrappedField(), type);
91         int divisor = iDivisor = remainderField.iDivisor;
92         iDurationField = remainderField.iRangeField;
93
94         DateTimeField field = getWrappedField();
95         int i = field.getMinimumValue();
96         int min = (i >= 0) ? i / divisor : ((i + 1) / divisor - 1);
97
98         int j = field.getMaximumValue();
99         int max = (j >= 0) ? j / divisor : ((j + 1) / divisor - 1);
100
101         iMin = min;
102         iMax = max;
103     }
104
105     /**
106      * Get the amount of scaled units from the specified time instant.
107      *
108      * @param instant the time instant in millis to query.
109      * @return the amount of scaled units extracted from the input.
110      */

111     public int get(long instant) {
112         int value = getWrappedField().get(instant);
113         if (value >= 0) {
114             return value / iDivisor;
115         } else {
116             return ((value + 1) / iDivisor) - 1;
117         }
118     }
119
120     /**
121      * Add the specified amount of scaled units to the specified time
122      * instant. The amount added may be negative.
123      *
124      * @param instant the time instant in millis to update.
125      * @param amount the amount of scaled units to add (can be negative).
126      * @return the updated time instant.
127      */

128     public long add(long instant, int amount) {
129         return getWrappedField().add(instant, amount * iDivisor);
130     }
131
132     /**
133      * Add the specified amount of scaled units to the specified time
134      * instant. The amount added may be negative.
135      *
136      * @param instant the time instant in millis to update.
137      * @param amount the amount of scaled units to add (can be negative).
138      * @return the updated time instant.
139      */

140     public long add(long instant, long amount) {
141         return getWrappedField().add(instant, amount * iDivisor);
142     }
143
144     /**
145      * Add to the scaled component of the specified time instant,
146      * wrapping around within that component if necessary.
147      *
148      * @param instant the time instant in millis to update.
149      * @param amount the amount of scaled units to add (can be negative).
150      * @return the updated time instant.
151      */

152     public long addWrapField(long instant, int amount) {
153         return set(instant, FieldUtils.getWrappedValue(get(instant), amount, iMin, iMax));
154     }
155
156     public int getDifference(long minuendInstant, long subtrahendInstant) {
157         return getWrappedField().getDifference(minuendInstant, subtrahendInstant) / iDivisor;
158     }
159
160     public long getDifferenceAsLong(long minuendInstant, long subtrahendInstant) {
161         return getWrappedField().getDifferenceAsLong(minuendInstant, subtrahendInstant) / iDivisor;
162     }
163
164     /**
165      * Set the specified amount of scaled units to the specified time instant.
166      *
167      * @param instant the time instant in millis to update.
168      * @param value value of scaled units to set.
169      * @return the updated time instant.
170      * @throws IllegalArgumentException if value is too large or too small.
171      */

172     public long set(long instant, int value) {
173         FieldUtils.verifyValueBounds(this, value, iMin, iMax);
174         int remainder = getRemainder(getWrappedField().get(instant));
175         return getWrappedField().set(instant, value * iDivisor + remainder);
176     }
177
178     /**
179      * Returns a scaled version of the wrapped field's unit duration field.
180      */

181     public DurationField getDurationField() {
182         return iDurationField;
183     }
184
185     /**
186      * Get the minimum value for the field.
187      *
188      * @return the minimum value
189      */

190     public int getMinimumValue() {
191         return iMin;
192     }
193
194     /**
195      * Get the maximum value for the field.
196      *
197      * @return the maximum value
198      */

199     public int getMaximumValue() {
200         return iMax;
201     }
202
203     public long roundFloor(long instant) {
204         DateTimeField field = getWrappedField();
205         return field.roundFloor(field.set(instant, get(instant) * iDivisor));
206     }
207
208     public long remainder(long instant) {
209         return set(instant, get(getWrappedField().remainder(instant)));
210     }
211
212     /**
213      * Returns the divisor applied, in the field's units.
214      *
215      * @return the divisor
216      */

217     public int getDivisor() {
218         return iDivisor;
219     }
220
221     private int getRemainder(int value) {
222         if (value >= 0) {
223             return value % iDivisor;
224         } else {
225             return (iDivisor - 1) + ((value + 1) % iDivisor);
226         }
227     }
228
229 }
230
Popular Tags