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
021 /**
022 * Wraps another field such that a certain value is added back into
023 * the sequence of numbers.
024 * <p>
025 * This reverses the effect of SkipDateTimeField. This isn't very
026 * elegant.
027 * <p>
028 * SkipUndoDateTimeField is thread-safe and immutable.
029 *
030 * @author Brian S O'Neill
031 * @author Stephen Colebourne
032 * @since 1.0
033 */
034 public final class SkipUndoDateTimeField extends DelegatedDateTimeField {
035
036 /** Serialization version. */
037 private static final long serialVersionUID = -5875876968979L;
038
039 /** The chronology to wrap. */
040 private final Chronology iChronology;
041 /** The value to skip. */
042 private final int iSkip;
043 /** The calculated minimum value. */
044 private transient int iMinValue;
045
046 /**
047 * Constructor that reinserts zero.
048 *
049 * @param chronology the chronoogy to use
050 * @param field the field to skip zero on
051 */
052 public SkipUndoDateTimeField(Chronology chronology, DateTimeField field) {
053 this(chronology, field, 0);
054 }
055
056 /**
057 * Constructor.
058 *
059 * @param chronology the chronoogy to use
060 * @param field the field to skip zero on
061 * @param skip the value to skip
062 */
063 public SkipUndoDateTimeField(Chronology chronology, DateTimeField field, int skip) {
064 super(field);
065 iChronology = chronology;
066 int min = super.getMinimumValue();
067 if (min < skip) {
068 iMinValue = min + 1;
069 } else if (min == skip + 1) {
070 iMinValue = skip;
071 } else {
072 iMinValue = min;
073 }
074 iSkip = skip;
075 }
076
077 //-----------------------------------------------------------------------
078 public int get(long millis) {
079 int value = super.get(millis);
080 if (value < iSkip) {
081 value++;
082 }
083 return value;
084 }
085
086 public long set(long millis, int value) {
087 FieldUtils.verifyValueBounds(this, value, iMinValue, getMaximumValue());
088 if (value <= iSkip) {
089 value--;
090 }
091 return super.set(millis, value);
092 }
093
094 public int getMinimumValue() {
095 return iMinValue;
096 }
097
098 private Object readResolve() {
099 return getType().getField(iChronology);
100 }
101
102 }