001 /*
002 * Copyright 2001-2005 Stephen Colebourne
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.joda.time.field;
017
018 import org.joda.time.DateTimeField;
019 import org.joda.time.DateTimeFieldType;
020 import org.joda.time.DurationField;
021 import org.joda.time.ReadablePartial;
022
023 /**
024 * Wraps another field such that zero values are replaced with one more than
025 * it's maximum. This is particularly useful for implementing an clockhourOfDay
026 * field, where the midnight value of 0 is replaced with 24.
027 * <p>
028 * ZeroIsMaxDateTimeField is thread-safe and immutable.
029 *
030 * @author Brian S O'Neill
031 * @since 1.0
032 */
033 public final class ZeroIsMaxDateTimeField extends DecoratedDateTimeField {
034
035 private static final long serialVersionUID = 961749798233026866L;
036
037 /**
038 * Constructor.
039 *
040 * @param field the base field
041 * @param type the field type this field will actually use
042 * @throws IllegalArgumentException if wrapped field's minimum value is not zero
043 */
044 public ZeroIsMaxDateTimeField(DateTimeField field, DateTimeFieldType type) {
045 super(field, type);
046 if (field.getMinimumValue() != 0) {
047 throw new IllegalArgumentException("Wrapped field's minumum value must be zero");
048 }
049 }
050
051 public int get(long instant) {
052 int value = getWrappedField().get(instant);
053 if (value == 0) {
054 value = getMaximumValue();
055 }
056 return value;
057 }
058
059 public long add(long instant, int value) {
060 return getWrappedField().add(instant, value);
061 }
062
063 public long add(long instant, long value) {
064 return getWrappedField().add(instant, value);
065 }
066
067 public long addWrapField(long instant, int value) {
068 return getWrappedField().addWrapField(instant, value);
069 }
070
071 public int[] addWrapField(ReadablePartial instant, int fieldIndex, int[] values, int valueToAdd) {
072 return getWrappedField().addWrapField(instant, fieldIndex, values, valueToAdd);
073 }
074
075 public int getDifference(long minuendInstant, long subtrahendInstant) {
076 return getWrappedField().getDifference(minuendInstant, subtrahendInstant);
077 }
078
079 public long getDifferenceAsLong(long minuendInstant, long subtrahendInstant) {
080 return getWrappedField().getDifferenceAsLong(minuendInstant, subtrahendInstant);
081 }
082
083 public long set(long instant, int value) {
084 int max = getMaximumValue();
085 FieldUtils.verifyValueBounds(this, value, 1, max);
086 if (value == max) {
087 value = 0;
088 }
089 return getWrappedField().set(instant, value);
090 }
091
092 public boolean isLeap(long instant) {
093 return getWrappedField().isLeap(instant);
094 }
095
096 public int getLeapAmount(long instant) {
097 return getWrappedField().getLeapAmount(instant);
098 }
099
100 public DurationField getLeapDurationField() {
101 return getWrappedField().getLeapDurationField();
102 }
103
104 /**
105 * Always returns 1.
106 *
107 * @return the minimum value of 1
108 */
109 public int getMinimumValue() {
110 return 1;
111 }
112
113 /**
114 * Always returns 1.
115 *
116 * @return the minimum value of 1
117 */
118 public int getMinimumValue(long instant) {
119 return 1;
120 }
121
122 /**
123 * Always returns 1.
124 *
125 * @return the minimum value of 1
126 */
127 public int getMinimumValue(ReadablePartial instant) {
128 return 1;
129 }
130
131 /**
132 * Always returns 1.
133 *
134 * @return the minimum value of 1
135 */
136 public int getMinimumValue(ReadablePartial instant, int[] values) {
137 return 1;
138 }
139
140 /**
141 * Get the maximum value for the field, which is one more than the wrapped
142 * field's maximum value.
143 *
144 * @return the maximum value
145 */
146 public int getMaximumValue() {
147 return getWrappedField().getMaximumValue() + 1;
148 }
149
150 /**
151 * Get the maximum value for the field, which is one more than the wrapped
152 * field's maximum value.
153 *
154 * @return the maximum value
155 */
156 public int getMaximumValue(long instant) {
157 return getWrappedField().getMaximumValue(instant) + 1;
158 }
159
160 /**
161 * Get the maximum value for the field, which is one more than the wrapped
162 * field's maximum value.
163 *
164 * @return the maximum value
165 */
166 public int getMaximumValue(ReadablePartial instant) {
167 return getWrappedField().getMaximumValue(instant) + 1;
168 }
169
170 /**
171 * Get the maximum value for the field, which is one more than the wrapped
172 * field's maximum value.
173 *
174 * @return the maximum value
175 */
176 public int getMaximumValue(ReadablePartial instant, int[] values) {
177 return getWrappedField().getMaximumValue(instant, values) + 1;
178 }
179
180 public long roundFloor(long instant) {
181 return getWrappedField().roundFloor(instant);
182 }
183
184 public long roundCeiling(long instant) {
185 return getWrappedField().roundCeiling(instant);
186 }
187
188 public long roundHalfFloor(long instant) {
189 return getWrappedField().roundHalfFloor(instant);
190 }
191
192 public long roundHalfCeiling(long instant) {
193 return getWrappedField().roundHalfCeiling(instant);
194 }
195
196 public long roundHalfEven(long instant) {
197 return getWrappedField().roundHalfEven(instant);
198 }
199
200 public long remainder(long instant) {
201 return getWrappedField().remainder(instant);
202 }
203
204 }