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.Chronology;
19 import org.joda.time.DateTimeField;
20 import org.joda.time.DateTimeFieldType;
21 import org.joda.time.IllegalFieldValueException;
22
23 /**
24 * Wraps another field such that a certain value is skipped.
25 * <p>
26 * This is most useful for years where you want to skip zero, so the
27 * sequence runs ...,2,1,-1,-2,...
28 * <p>
29 * SkipDateTimeField is thread-safe and immutable.
30 *
31 * @author Brian S O'Neill
32 * @author Stephen Colebourne
33 * @since 1.0
34 */
35 public final class SkipDateTimeField extends DelegatedDateTimeField {
36
37 /** Serialization version. */
38 private static final long serialVersionUID = -8869148464118507846L;
39
40 /** The chronology to wrap. */
41 private final Chronology iChronology;
42 /** The value to skip. */
43 private final int iSkip;
44 /** The calculated minimum value. */
45 private transient int iMinValue;
46
47 /**
48 * Constructor that skips zero.
49 *
50 * @param chronology the chronoogy to use
51 * @param field the field to skip zero on
52 */
53 public SkipDateTimeField(Chronology chronology, DateTimeField field) {
54 this(chronology, field, 0);
55 }
56
57 /**
58 * Constructor.
59 *
60 * @param chronology the chronoogy to use
61 * @param field the field to skip zero on
62 * @param skip the value to skip
63 */
64 public SkipDateTimeField(Chronology chronology, DateTimeField field, int skip) {
65 super(field);
66 iChronology = chronology;
67 int min = super.getMinimumValue();
68 if (min < skip) {
69 iMinValue = min - 1;
70 } else if (min == skip) {
71 iMinValue = skip + 1;
72 } else {
73 iMinValue = min;
74 }
75 iSkip = skip;
76 }
77
78 //-----------------------------------------------------------------------
79 public int get(long millis) {
80 int value = super.get(millis);
81 if (value <= iSkip) {
82 value--;
83 }
84 return value;
85 }
86
87 public long set(long millis, int value) {
88 FieldUtils.verifyValueBounds(this, value, iMinValue, getMaximumValue());
89 if (value <= iSkip) {
90 if (value == iSkip) {
91 throw new IllegalFieldValueException
92 (DateTimeFieldType.year(), Integer.valueOf(value), null, null);
93 }
94 value++;
95 }
96 return super.set(millis, value);
97 }
98
99 public int getMinimumValue() {
100 return iMinValue;
101 }
102
103 private Object readResolve() {
104 return getType().getField(iChronology);
105 }
106
107 }