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.Chronology;
019: import org.joda.time.DateTimeField;
020: import org.joda.time.DateTimeFieldType;
021: import org.joda.time.IllegalFieldValueException;
022:
023: /**
024: * Wraps another field such that a certain value is skipped.
025: * <p>
026: * This is most useful for years where you want to skip zero, so the
027: * sequence runs ...,2,1,-1,-2,...
028: * <p>
029: * SkipDateTimeField is thread-safe and immutable.
030: *
031: * @author Brian S O'Neill
032: * @author Stephen Colebourne
033: * @since 1.0
034: */
035: public final class SkipDateTimeField extends DelegatedDateTimeField {
036:
037: /** Serialization version. */
038: private static final long serialVersionUID = -8869148464118507846L;
039:
040: /** The chronology to wrap. */
041: private final Chronology iChronology;
042: /** The value to skip. */
043: private final int iSkip;
044: /** The calculated minimum value. */
045: private transient int iMinValue;
046:
047: /**
048: * Constructor that skips zero.
049: *
050: * @param chronology the chronoogy to use
051: * @param field the field to skip zero on
052: */
053: public SkipDateTimeField(Chronology chronology, DateTimeField field) {
054: this (chronology, field, 0);
055: }
056:
057: /**
058: * Constructor.
059: *
060: * @param chronology the chronoogy to use
061: * @param field the field to skip zero on
062: * @param skip the value to skip
063: */
064: public SkipDateTimeField(Chronology chronology,
065: DateTimeField field, int skip) {
066: super (field);
067: iChronology = chronology;
068: int min = super .getMinimumValue();
069: if (min < skip) {
070: iMinValue = min - 1;
071: } else if (min == skip) {
072: iMinValue = skip + 1;
073: } else {
074: iMinValue = min;
075: }
076: iSkip = skip;
077: }
078:
079: //-----------------------------------------------------------------------
080: public int get(long millis) {
081: int value = super .get(millis);
082: if (value <= iSkip) {
083: value--;
084: }
085: return value;
086: }
087:
088: public long set(long millis, int value) {
089: FieldUtils.verifyValueBounds(this , value, iMinValue,
090: getMaximumValue());
091: if (value <= iSkip) {
092: if (value == iSkip) {
093: throw new IllegalFieldValueException(DateTimeFieldType
094: .year(), new Integer(value), null, null);
095: }
096: value++;
097: }
098: return super .set(millis, value);
099: }
100:
101: public int getMinimumValue() {
102: return iMinValue;
103: }
104:
105: private Object readResolve() {
106: return getType().getField(iChronology);
107: }
108:
109: }
|