001 /* 002 * Copyright 2001-2009 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; 017 018 /** 019 * Defines the calculation engine for duration fields. 020 * The interface defines a set of methods that manipulate a millisecond duration 021 * with regards to a single field, such as months or seconds. 022 * <p> 023 * This design is extensible so, if you wish, you can extract a different field from 024 * the millisecond duration. A number of standard implementations are provided to assist. 025 * 026 * @author Stephen Colebourne 027 * @author Brian S O'Neill 028 * @since 1.0 029 */ 030 public abstract class DurationField implements Comparable<DurationField> { 031 032 /** 033 * Get the type of the field. 034 * 035 * @return field type 036 */ 037 public abstract DurationFieldType getType(); 038 039 /** 040 * Get the name of the field. 041 * <p> 042 * By convention, names are plural. 043 * 044 * @return field name 045 */ 046 public abstract String getName(); 047 048 /** 049 * Returns true if this field is supported. 050 * 051 * @return true if this field is supported 052 */ 053 public abstract boolean isSupported(); 054 055 /** 056 * Is this field precise. A precise field can calculate its value from 057 * milliseconds without needing a reference date. Put another way, a 058 * precise field's unit size is not variable. 059 * 060 * @return true if precise 061 * @see #getUnitMillis() 062 */ 063 public abstract boolean isPrecise(); 064 065 /** 066 * Returns the amount of milliseconds per unit value of this field. For 067 * example, if this field represents "seconds", then this returns the 068 * milliseconds in one second. 069 * <p> 070 * For imprecise fields, the unit size is variable, and so this method 071 * returns a suitable average value. 072 * 073 * @return the unit size of this field, in milliseconds 074 * @see #isPrecise() 075 */ 076 public abstract long getUnitMillis(); 077 078 //------------------------------------------------------------------------ 079 /** 080 * Get the value of this field from the milliseconds, which is approximate 081 * if this field is imprecise. 082 * 083 * @param duration the milliseconds to query, which may be negative 084 * @return the value of the field, in the units of the field, which may be 085 * negative 086 * @throws ArithmeticException if the value is too large for an int 087 */ 088 public abstract int getValue(long duration); 089 090 /** 091 * Get the value of this field from the milliseconds, which is approximate 092 * if this field is imprecise. 093 * 094 * @param duration the milliseconds to query, which may be negative 095 * @return the value of the field, in the units of the field, which may be 096 * negative 097 */ 098 public abstract long getValueAsLong(long duration); 099 100 /** 101 * Get the value of this field from the milliseconds relative to an 102 * instant. For precise fields this method produces the same result as for 103 * the single argument get method. 104 * <p> 105 * If the millisecond duration is positive, then the instant is treated as a 106 * "start instant". If negative, the instant is treated as an "end instant". 107 * 108 * @param duration the milliseconds to query, which may be negative 109 * @param instant the start instant to calculate relative to 110 * @return the value of the field, in the units of the field, which may be 111 * negative 112 * @throws ArithmeticException if the value is too large for an int 113 */ 114 public abstract int getValue(long duration, long instant); 115 116 /** 117 * Get the value of this field from the milliseconds relative to an 118 * instant. For precise fields this method produces the same result as for 119 * the single argument get method. 120 * <p> 121 * If the millisecond duration is positive, then the instant is treated as a 122 * "start instant". If negative, the instant is treated as an "end instant". 123 * 124 * @param duration the milliseconds to query, which may be negative 125 * @param instant the start instant to calculate relative to 126 * @return the value of the field, in the units of the field, which may be 127 * negative 128 */ 129 public abstract long getValueAsLong(long duration, long instant); 130 131 //------------------------------------------------------------------------ 132 /** 133 * Get the millisecond duration of this field from its value, which is 134 * approximate if this field is imprecise. 135 * 136 * @param value the value of the field, which may be negative 137 * @return the milliseconds that the field represents, which may be 138 * negative 139 */ 140 public abstract long getMillis(int value); 141 142 /** 143 * Get the millisecond duration of this field from its value, which is 144 * approximate if this field is imprecise. 145 * 146 * @param value the value of the field, which may be negative 147 * @return the milliseconds that the field represents, which may be 148 * negative 149 */ 150 public abstract long getMillis(long value); 151 152 /** 153 * Get the millisecond duration of this field from its value relative to an 154 * instant. For precise fields this method produces the same result as for 155 * the single argument getMillis method. 156 * <p> 157 * If the value is positive, then the instant is treated as a "start 158 * instant". If negative, the instant is treated as an "end instant". 159 * 160 * @param value the value of the field, which may be negative 161 * @param instant the instant to calculate relative to 162 * @return the millisecond duration that the field represents, which may be 163 * negative 164 */ 165 public abstract long getMillis(int value, long instant); 166 167 /** 168 * Get the millisecond duration of this field from its value relative to an 169 * instant. For precise fields this method produces the same result as for 170 * the single argument getMillis method. 171 * <p> 172 * If the value is positive, then the instant is treated as a "start 173 * instant". If negative, the instant is treated as an "end instant". 174 * 175 * @param value the value of the field, which may be negative 176 * @param instant the instant to calculate relative to 177 * @return the millisecond duration that the field represents, which may be 178 * negative 179 */ 180 public abstract long getMillis(long value, long instant); 181 182 /** 183 * Adds a duration value (which may be negative) to the instant. 184 * 185 * @param instant the milliseconds from 1970-01-01T00:00:00Z to add to 186 * @param value the value to add, in the units of the field 187 * @return the updated milliseconds 188 */ 189 public abstract long add(long instant, int value); 190 191 /** 192 * Adds a duration value (which may be negative) to the instant. 193 * 194 * @param instant the milliseconds from 1970-01-01T00:00:00Z to add to 195 * @param value the value to add, in the units of the field 196 * @return the updated milliseconds 197 */ 198 public abstract long add(long instant, long value); 199 200 /** 201 * Subtracts a duration value (which may be negative) from the instant. 202 * 203 * @param instant the milliseconds from 1970-01-01T00:00:00Z to subtract from 204 * @param value the value to subtract, in the units of the field 205 * @return the updated milliseconds 206 * @since 1.1 207 */ 208 public long subtract(long instant, int value) { 209 if (value == Integer.MIN_VALUE) { 210 return subtract(instant, (long) value); 211 } 212 return add(instant, -value); 213 } 214 215 /** 216 * Subtracts a duration value (which may be negative) from the instant. 217 * 218 * @param instant the milliseconds from 1970-01-01T00:00:00Z to subtract from 219 * @param value the value to subtract, in the units of the field 220 * @return the updated milliseconds 221 * @since 1.1 222 */ 223 public long subtract(long instant, long value) { 224 if (value == Long.MIN_VALUE) { 225 throw new ArithmeticException("Long.MIN_VALUE cannot be negated"); 226 } 227 return add(instant, -value); 228 } 229 230 /** 231 * Computes the difference between two instants, as measured in the units 232 * of this field. Any fractional units are dropped from the result. Calling 233 * getDifference reverses the effect of calling add. In the following code: 234 * 235 * <pre> 236 * long instant = ... 237 * int v = ... 238 * int age = getDifference(add(instant, v), instant); 239 * </pre> 240 * 241 * The value 'age' is the same as the value 'v'. 242 * 243 * @param minuendInstant the milliseconds from 1970-01-01T00:00:00Z to 244 * subtract from 245 * @param subtrahendInstant the milliseconds from 1970-01-01T00:00:00Z to 246 * subtract off the minuend 247 * @return the difference in the units of this field 248 */ 249 public abstract int getDifference(long minuendInstant, long subtrahendInstant); 250 251 /** 252 * Computes the difference between two instants, as measured in the units 253 * of this field. Any fractional units are dropped from the result. Calling 254 * getDifference reverses the effect of calling add. In the following code: 255 * 256 * <pre> 257 * long instant = ... 258 * long v = ... 259 * long age = getDifferenceAsLong(add(instant, v), instant); 260 * </pre> 261 * 262 * The value 'age' is the same as the value 'v'. 263 * 264 * @param minuendInstant the milliseconds from 1970-01-01T00:00:00Z to 265 * subtract from 266 * @param subtrahendInstant the milliseconds from 1970-01-01T00:00:00Z to 267 * subtract off the minuend 268 * @return the difference in the units of this field 269 */ 270 public abstract long getDifferenceAsLong(long minuendInstant, long subtrahendInstant); 271 272 // Adding this definition would be backwards incompatible with earlier subclasses 273 // This definition of compareTo was present in previous versions, and still applies 274 // /** 275 // * Compares this duration field with another duration field for ascending 276 // * unit millisecond order. This ordering is inconsistent with equals, as it 277 // * ignores name and precision. 278 // * 279 // * @param durationField a duration field to check against 280 // * @return negative value if this is less, 0 if equal, or positive value if greater 281 // * @throws NullPointerException if the object is null 282 // * @throws ClassCastException if the object type is not supported 283 // */ 284 // public abstract int compareTo(DurationField durationField); 285 286 /** 287 * Returns a localized unit name of this field, using the given value as an 288 * aid. For example, the unit name may differ if it is plural. 289 * 290 * @param value the duration value to use for selecting a unit name 291 * @param locale the locale to use for selecting a name, null for default 292 */ 293 //String getUnitName(long value, Locale locale); 294 295 /** 296 * Returns a localized unit name of this field, using the given value as an 297 * aid. For example, the unit name may differ if it is plural. 298 * 299 * @param value the duration value to use for selecting a unit name 300 */ 301 //String getUnitName(long value); 302 303 /** 304 * Get the maximum length string returned by getUnitName. 305 * 306 * @param locale the locale to use for selecting a unit name, null for 307 * default 308 * @return the maximum name length 309 */ 310 //int getMaximumUnitNameLength(Locale locale); 311 312 //------------------------------------------------------------------------ 313 /** 314 * Get a suitable debug string. 315 * 316 * @return debug string 317 */ 318 public abstract String toString(); 319 320 }