1 /*
2  *  Copyright 2001-2013 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 import org.joda.time.ReadablePartial;
22
23 /**
24  * Wraps another field such that zero values are replaced with one more than
25  * it's maximum. This is particularly useful for implementing an clockhourOfDay
26  * field, where the midnight value of 0 is replaced with 24.
27  * <p>
28  * ZeroIsMaxDateTimeField is thread-safe and immutable.
29  *
30  * @author Brian S O'Neill
31  * @since 1.0
32  */

33 public final class ZeroIsMaxDateTimeField extends DecoratedDateTimeField {
34
35     @SuppressWarnings("unused")
36     private static final long serialVersionUID = 961749798233026866L;
37
38     /**
39      * Constructor.
40      * 
41      * @param field  the base field
42      * @param type  the field type this field will actually use
43      * @throws IllegalArgumentException if wrapped field's minimum value is not zero
44      */

45     public ZeroIsMaxDateTimeField(DateTimeField field, DateTimeFieldType type) {
46         super(field, type);
47         if (field.getMinimumValue() != 0) {
48             throw new IllegalArgumentException("Wrapped field's minumum value must be zero");
49         }
50     }
51
52     public int get(long instant) {
53         int value = getWrappedField().get(instant);
54         if (value == 0) {
55             value = getMaximumValue();
56         }
57         return value;
58     }
59
60     public long add(long instant, int value) {
61         return getWrappedField().add(instant, value);
62     }
63
64     public long add(long instant, long value) {
65         return getWrappedField().add(instant, value);
66     }
67
68     public long addWrapField(long instant, int value) {
69         return getWrappedField().addWrapField(instant, value);
70     }
71
72     public int[] addWrapField(ReadablePartial instant, int fieldIndex, int[] values, int valueToAdd) {
73         return getWrappedField().addWrapField(instant, fieldIndex, values, valueToAdd);
74     }
75
76     public int getDifference(long minuendInstant, long subtrahendInstant) {
77         return getWrappedField().getDifference(minuendInstant, subtrahendInstant);
78     }
79
80     public long getDifferenceAsLong(long minuendInstant, long subtrahendInstant) {
81         return getWrappedField().getDifferenceAsLong(minuendInstant, subtrahendInstant);
82     }
83
84     public long set(long instant, int value) {
85         int max = getMaximumValue();
86         FieldUtils.verifyValueBounds(this, value, 1, max);
87         if (value == max) {
88             value = 0;
89         }
90         return getWrappedField().set(instant, value);
91     }
92
93     public boolean isLeap(long instant) {
94         return getWrappedField().isLeap(instant);
95     }
96
97     public int getLeapAmount(long instant) {
98         return getWrappedField().getLeapAmount(instant);
99     }
100
101     public DurationField getLeapDurationField() {
102         return getWrappedField().getLeapDurationField();
103     }
104
105     /**
106      * Always returns 1.
107      * 
108      * @return the minimum value of 1
109      */

110     public int getMinimumValue() {
111         return 1;
112     }
113
114     /**
115      * Always returns 1.
116      * 
117      * @return the minimum value of 1
118      */

119     public int getMinimumValue(long instant) {
120         return 1;
121     }
122
123     /**
124      * Always returns 1.
125      * 
126      * @return the minimum value of 1
127      */

128     public int getMinimumValue(ReadablePartial instant) {
129         return 1;
130     }
131
132     /**
133      * Always returns 1.
134      * 
135      * @return the minimum value of 1
136      */

137     public int getMinimumValue(ReadablePartial instant, int[] values) {
138         return 1;
139     }
140
141     /**
142      * Get the maximum value for the field, which is one more than the wrapped
143      * field's maximum value.
144      * 
145      * @return the maximum value
146      */

147     public int getMaximumValue() {
148         return getWrappedField().getMaximumValue() + 1;
149     }
150
151     /**
152      * Get the maximum value for the field, which is one more than the wrapped
153      * field's maximum value.
154      * 
155      * @return the maximum value
156      */

157     public int getMaximumValue(long instant) {
158         return getWrappedField().getMaximumValue(instant) + 1;
159     }
160
161     /**
162      * Get the maximum value for the field, which is one more than the wrapped
163      * field's maximum value.
164      * 
165      * @return the maximum value
166      */

167     public int getMaximumValue(ReadablePartial instant) {
168         return getWrappedField().getMaximumValue(instant) + 1;
169     }
170
171     /**
172      * Get the maximum value for the field, which is one more than the wrapped
173      * field's maximum value.
174      * 
175      * @return the maximum value
176      */

177     public int getMaximumValue(ReadablePartial instant, int[] values) {
178         return getWrappedField().getMaximumValue(instant, values) + 1;
179     }
180
181     public long roundFloor(long instant) {
182         return getWrappedField().roundFloor(instant);
183     }
184
185     public long roundCeiling(long instant) {
186         return getWrappedField().roundCeiling(instant);
187     }
188
189     public long roundHalfFloor(long instant) {
190         return getWrappedField().roundHalfFloor(instant);
191     }
192
193     public long roundHalfCeiling(long instant) {
194         return getWrappedField().roundHalfCeiling(instant);
195     }
196
197     public long roundHalfEven(long instant) {
198         return getWrappedField().roundHalfEven(instant);
199     }
200
201     public long remainder(long instant) {
202         return getWrappedField().remainder(instant);
203     }
204
205 }
206