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 }