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 }