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;
017
018 import java.util.Locale;
019
020 /**
021 * Defines the calculation engine for date and time fields.
022 * The interface defines a set of methods that manipulate a millisecond datetime
023 * with regards to a single field, such as monthOfYear or secondOfMinute.
024 * <p>
025 * This design is extensible so, if you wish, you can extract a different field from
026 * the milliseconds. A number of standard implementations are provided to assist.
027 *
028 * @author Guy Allard
029 * @author Stephen Colebourne
030 * @author Brian S O'Neill
031 * @since 1.0
032 */
033 public abstract class DateTimeField {
034
035 /**
036 * Get the type of the field.
037 *
038 * @return field type
039 */
040 public abstract DateTimeFieldType getType();
041
042 /**
043 * Get the name of the field.
044 * <p>
045 * By convention, names follow a pattern of "dddOfRrr", where "ddd" represents
046 * the (singular) duration unit field name and "Rrr" represents the (singular)
047 * duration range field name. If the range field is not applicable, then
048 * the name of the field is simply the (singular) duration field name.
049 *
050 * @return field name
051 */
052 public abstract String getName();
053
054 /**
055 * Returns true if this field is supported.
056 *
057 * @return true if this field is supported
058 */
059 public abstract boolean isSupported();
060
061 /**
062 * Returns true if the set method is lenient. If so, it accepts values that
063 * are out of bounds. For example, a lenient day of month field accepts 32
064 * for January, converting it to February 1.
065 *
066 * @return true if this field is lenient
067 */
068 public abstract boolean isLenient();
069
070 // Main access API
071 //------------------------------------------------------------------------
072 /**
073 * Get the value of this field from the milliseconds.
074 *
075 * @param instant the milliseconds from 1970-01-01T00:00:00Z to query
076 * @return the value of the field, in the units of the field
077 */
078 public abstract int get(long instant);
079
080 /**
081 * Get the human-readable, text value of this field from the milliseconds.
082 * If the specified locale is null, the default locale is used.
083 *
084 * @param instant the milliseconds from 1970-01-01T00:00:00Z to query
085 * @param locale the locale to use for selecting a text symbol, null for default
086 * @return the text value of the field
087 */
088 public abstract String getAsText(long instant, Locale locale);
089
090 /**
091 * Get the human-readable, text value of this field from the milliseconds.
092 *
093 * @param instant the milliseconds from 1970-01-01T00:00:00Z to query
094 * @return the text value of the field
095 */
096 public abstract String getAsText(long instant);
097
098 /**
099 * Get the human-readable, text value of this field from a partial instant.
100 * If the specified locale is null, the default locale is used.
101 *
102 * @param partial the partial instant to query
103 * @param fieldValue the field value of this field, provided for performance
104 * @param locale the locale to use for selecting a text symbol, null for default
105 * @return the text value of the field
106 */
107 public abstract String getAsText(ReadablePartial partial, int fieldValue, Locale locale);
108
109 /**
110 * Get the human-readable, text value of this field from a partial instant.
111 * If the specified locale is null, the default locale is used.
112 *
113 * @param partial the partial instant to query
114 * @param locale the locale to use for selecting a text symbol, null for default
115 * @return the text value of the field
116 */
117 public abstract String getAsText(ReadablePartial partial, Locale locale);
118
119 /**
120 * Get the human-readable, text value of this field from the field value.
121 * If the specified locale is null, the default locale is used.
122 *
123 * @param fieldValue the numeric value to convert to text
124 * @param locale the locale to use for selecting a text symbol, null for default
125 * @return the text value of the field
126 */
127 public abstract String getAsText(int fieldValue, Locale locale);
128
129 /**
130 * Get the human-readable, short text value of this field from the
131 * milliseconds. If the specified locale is null, the default locale is used.
132 *
133 * @param instant the milliseconds from 1970-01-01T00:00:00Z to query
134 * @param locale the locale to use for selecting a text symbol, null for default
135 * @return the short text value of the field
136 */
137 public abstract String getAsShortText(long instant, Locale locale);
138
139 /**
140 * Get the human-readable, short text value of this field from the
141 * milliseconds.
142 *
143 * @param instant the milliseconds from 1970-01-01T00:00:00Z to query
144 * @return the short text value of the field
145 */
146 public abstract String getAsShortText(long instant);
147
148 /**
149 * Get the human-readable, short text value of this field from a partial instant.
150 * If the specified locale is null, the default locale is used.
151 *
152 * @param partial the partial instant to query
153 * @param fieldValue the field value of this field, provided for performance
154 * @param locale the locale to use for selecting a text symbol, null for default
155 * @return the text value of the field
156 */
157 public abstract String getAsShortText(ReadablePartial partial, int fieldValue, Locale locale);
158
159 /**
160 * Get the human-readable, short text value of this field from a partial instant.
161 * If the specified locale is null, the default locale is used.
162 *
163 * @param partial the partial instant to query
164 * @param locale the locale to use for selecting a text symbol, null for default
165 * @return the text value of the field
166 */
167 public abstract String getAsShortText(ReadablePartial partial, Locale locale);
168
169 /**
170 * Get the human-readable, short text value of this field from the field value.
171 * If the specified locale is null, the default locale is used.
172 *
173 * @param fieldValue the numeric value to convert to text
174 * @param locale the locale to use for selecting a text symbol, null for default
175 * @return the text value of the field
176 */
177 public abstract String getAsShortText(int fieldValue, Locale locale);
178
179 /**
180 * Adds a value (which may be negative) to the millis value,
181 * overflowing into larger fields if necessary.
182 * <p>
183 * The value will be added to this field. If the value is too large to be
184 * added solely to this field, larger fields will increase as required.
185 * Smaller fields should be unaffected, except where the result would be
186 * an invalid value for a smaller field. In this case the smaller field is
187 * adjusted to be in range.
188 * <p>
189 * For example, in the ISO chronology:<br>
190 * 2000-08-20 add six months is 2001-02-20<br>
191 * 2000-08-20 add twenty months is 2002-04-20<br>
192 * 2000-08-20 add minus nine months is 1999-11-20<br>
193 * 2001-01-31 add one month is 2001-02-28<br>
194 * 2001-01-31 add two months is 2001-03-31<br>
195 *
196 * @param instant the milliseconds from 1970-01-01T00:00:00Z to add to
197 * @param value the value to add, in the units of the field
198 * @return the updated milliseconds
199 */
200 public abstract long add(long instant, int value);
201
202 /**
203 * Adds a value (which may be negative) to the millis value,
204 * overflowing into larger fields if necessary.
205 *
206 * @param instant the milliseconds from 1970-01-01T00:00:00Z to add to
207 * @param value the long value to add, in the units of the field
208 * @return the updated milliseconds
209 * @throws IllegalArgumentException if value is too large
210 * @see #add(long,int)
211 */
212 public abstract long add(long instant, long value);
213
214 /**
215 * Adds a value (which may be negative) to the partial instant,
216 * throwing an exception if the maximum size of the instant is reached.
217 * <p>
218 * The value will be added to this field, overflowing into larger fields
219 * if necessary. Smaller fields should be unaffected, except where the
220 * result would be an invalid value for a smaller field. In this case the
221 * smaller field is adjusted to be in range.
222 * <p>
223 * Partial instants only contain some fields. This may result in a maximum
224 * possible value, such as TimeOfDay being limited to 23:59:59:999. If this
225 * limit is breached by the add an exception is thrown.
226 * <p>
227 * For example, in the ISO chronology:<br>
228 * 2000-08-20 add six months is 2000-02-20<br>
229 * 2000-08-20 add twenty months is 2000-04-20<br>
230 * 2000-08-20 add minus nine months is 2000-11-20<br>
231 * 2001-01-31 add one month is 2001-02-28<br>
232 * 2001-01-31 add two months is 2001-03-31<br>
233 *
234 * @param instant the partial instant
235 * @param fieldIndex the index of this field in the instant
236 * @param values the values of the partial instant which should be updated
237 * @param valueToAdd the value to add, in the units of the field
238 * @return the passed in values
239 * @throws IllegalArgumentException if the value is invalid or the maximum instant is reached
240 */
241 public abstract int[] add(ReadablePartial instant, int fieldIndex, int[] values, int valueToAdd);
242
243 /**
244 * Adds a value (which may be negative) to the partial instant,
245 * wrapping the whole partial if the maximum size of the partial is reached.
246 * <p>
247 * The value will be added to this field, overflowing into larger fields
248 * if necessary. Smaller fields should be unaffected, except where the
249 * result would be an invalid value for a smaller field. In this case the
250 * smaller field is adjusted to be in range.
251 * <p>
252 * Partial instants only contain some fields. This may result in a maximum
253 * possible value, such as TimeOfDay normally being limited to 23:59:59:999.
254 * If ths limit is reached by the addition, this method will wrap back to
255 * 00:00:00.000. In fact, you would generally only use this method for
256 * classes that have a limitation such as this.
257 * <p>
258 * For example, in the ISO chronology:<br>
259 * 10:20:30 add 20 minutes is 10:40:30<br>
260 * 10:20:30 add 45 minutes is 11:05:30<br>
261 * 10:20:30 add 16 hours is 02:20:30<br>
262 *
263 * @param instant the partial instant
264 * @param fieldIndex the index of this field in the partial
265 * @param values the values of the partial instant which should be updated
266 * @param valueToAdd the value to add, in the units of the field
267 * @return the passed in values
268 * @throws IllegalArgumentException if the value is invalid or the maximum instant is reached
269 */
270 public abstract int[] addWrapPartial(ReadablePartial instant, int fieldIndex, int[] values, int valueToAdd);
271
272 /**
273 * Adds a value (which may be negative) to the millis value,
274 * wrapping within this field.
275 * <p>
276 * The value will be added to this field. If the value is too large to be
277 * added solely to this field then it wraps. Larger fields are always
278 * unaffected. Smaller fields should be unaffected, except where the
279 * result would be an invalid value for a smaller field. In this case the
280 * smaller field is adjusted to be in range.
281 * <p>
282 * For example, in the ISO chronology:<br>
283 * 2000-08-20 addWrapField six months is 2000-02-20<br>
284 * 2000-08-20 addWrapField twenty months is 2000-04-20<br>
285 * 2000-08-20 addWrapField minus nine months is 2000-11-20<br>
286 * 2001-01-31 addWrapField one month is 2001-02-28<br>
287 * 2001-01-31 addWrapField two months is 2001-03-31<br>
288 *
289 * @param instant the milliseconds from 1970-01-01T00:00:00Z to add to
290 * @param value the value to add, in the units of the field
291 * @return the updated milliseconds
292 */
293 public abstract long addWrapField(long instant, int value) ;
294
295 /**
296 * Adds a value (which may be negative) to the partial instant,
297 * wrapping within this field.
298 * <p>
299 * The value will be added to this field. If the value is too large to be
300 * added solely to this field then it wraps. Larger fields are always
301 * unaffected. Smaller fields should be unaffected, except where the
302 * result would be an invalid value for a smaller field. In this case the
303 * smaller field is adjusted to be in range.
304 * <p>
305 * For example, in the ISO chronology:<br>
306 * 2000-08-20 addWrapField six months is 2000-02-20<br>
307 * 2000-08-20 addWrapField twenty months is 2000-04-20<br>
308 * 2000-08-20 addWrapField minus nine months is 2000-11-20<br>
309 * 2001-01-31 addWrapField one month is 2001-02-28<br>
310 * 2001-01-31 addWrapField two months is 2001-03-31<br>
311 *
312 * @param instant the partial instant
313 * @param fieldIndex the index of this field in the instant
314 * @param values the values of the partial instant which should be updated
315 * @param valueToAdd the value to add, in the units of the field
316 * @return the passed in values
317 * @throws IllegalArgumentException if the value is invalid
318 */
319 public abstract int[] addWrapField(ReadablePartial instant, int fieldIndex, int[] values, int valueToAdd);
320
321 /**
322 * Computes the difference between two instants, as measured in the units
323 * of this field. Any fractional units are dropped from the result. Calling
324 * getDifference reverses the effect of calling add. In the following code:
325 *
326 * <pre>
327 * long instant = ...
328 * int v = ...
329 * int age = getDifference(add(instant, v), instant);
330 * </pre>
331 *
332 * The value 'age' is the same as the value 'v'.
333 *
334 * @param minuendInstant the milliseconds from 1970-01-01T00:00:00Z to
335 * subtract from
336 * @param subtrahendInstant the milliseconds from 1970-01-01T00:00:00Z to
337 * subtract off the minuend
338 * @return the difference in the units of this field
339 */
340 public abstract int getDifference(long minuendInstant, long subtrahendInstant);
341
342 /**
343 * Computes the difference between two instants, as measured in the units
344 * of this field. Any fractional units are dropped from the result. Calling
345 * getDifference reverses the effect of calling add. In the following code:
346 *
347 * <pre>
348 * long instant = ...
349 * long v = ...
350 * long age = getDifferenceAsLong(add(instant, v), instant);
351 * </pre>
352 *
353 * The value 'age' is the same as the value 'v'.
354 *
355 * @param minuendInstant the milliseconds from 1970-01-01T00:00:00Z to
356 * subtract from
357 * @param subtrahendInstant the milliseconds from 1970-01-01T00:00:00Z to
358 * subtract off the minuend
359 * @return the difference in the units of this field
360 */
361 public abstract long getDifferenceAsLong(long minuendInstant, long subtrahendInstant);
362
363 /**
364 * Sets a value in the milliseconds supplied.
365 * <p>
366 * The value of this field will be set.
367 * If the value is invalid, an exception if thrown.
368 * <p>
369 * If setting this field would make other fields invalid, then those fields
370 * may be changed. For example if the current date is the 31st January, and
371 * the month is set to February, the day would be invalid. Instead, the day
372 * would be changed to the closest value - the 28th/29th February as appropriate.
373 *
374 * @param instant the milliseconds from 1970-01-01T00:00:00Z to set in
375 * @param value the value to set, in the units of the field
376 * @return the updated milliseconds
377 * @throws IllegalArgumentException if the value is invalid
378 */
379 public abstract long set(long instant, int value);
380
381 /**
382 * Sets a value using the specified partial instant.
383 * <p>
384 * The value of this field (specified by the index) will be set.
385 * If the value is invalid, an exception if thrown.
386 * <p>
387 * If setting this field would make other fields invalid, then those fields
388 * may be changed. For example if the current date is the 31st January, and
389 * the month is set to February, the day would be invalid. Instead, the day
390 * would be changed to the closest value - the 28th/29th February as appropriate.
391 *
392 * @param instant the partial instant
393 * @param fieldIndex the index of this field in the instant
394 * @param values the values of the partial instant which should be updated
395 * @param newValue the value to set, in the units of the field
396 * @return the passed in values
397 * @throws IllegalArgumentException if the value is invalid
398 */
399 public abstract int[] set(ReadablePartial instant, int fieldIndex, int[] values, int newValue);
400
401 /**
402 * Sets a value in the milliseconds supplied from a human-readable, text value.
403 * If the specified locale is null, the default locale is used.
404 * <p>
405 * If setting this field would make other fields invalid, then those fields
406 * may be changed. For example if the current date is the 31st January, and
407 * the month is set to February, the day would be invalid. Instead, the day
408 * would be changed to the closest value - the 28th/29th February as appropriate.
409 *
410 * @param instant the milliseconds from 1970-01-01T00:00:00Z to set in
411 * @param text the text value to set
412 * @param locale the locale to use for selecting a text symbol, null for default
413 * @return the updated milliseconds
414 * @throws IllegalArgumentException if the text value is invalid
415 */
416 public abstract long set(long instant, String text, Locale locale);
417
418 /**
419 * Sets a value in the milliseconds supplied from a human-readable, text value.
420 * <p>
421 * If setting this field would make other fields invalid, then those fields
422 * may be changed. For example if the current date is the 31st January, and
423 * the month is set to February, the day would be invalid. Instead, the day
424 * would be changed to the closest value - the 28th/29th February as appropriate.
425 *
426 * @param instant the milliseconds from 1970-01-01T00:00:00Z to set in
427 * @param text the text value to set
428 * @return the updated milliseconds
429 * @throws IllegalArgumentException if the text value is invalid
430 */
431 public abstract long set(long instant, String text);
432
433 /**
434 * Sets a value in the milliseconds supplied from a human-readable, text value.
435 * If the specified locale is null, the default locale is used.
436 * <p>
437 * If setting this field would make other fields invalid, then those fields
438 * may be changed. For example if the current date is the 31st January, and
439 * the month is set to February, the day would be invalid. Instead, the day
440 * would be changed to the closest value - the 28th/29th February as appropriate.
441 *
442 * @param instant the partial instant
443 * @param fieldIndex the index of this field in the instant
444 * @param values the values of the partial instant which should be updated
445 * @param text the text value to set
446 * @param locale the locale to use for selecting a text symbol, null for default
447 * @return the passed in values
448 * @throws IllegalArgumentException if the text value is invalid
449 */
450 public abstract int[] set(ReadablePartial instant, int fieldIndex, int[] values, String text, Locale locale);
451
452 // Extra information API
453 //------------------------------------------------------------------------
454 /**
455 * Returns the duration per unit value of this field. For example, if this
456 * field represents "hour of day", then the duration is an hour.
457 *
458 * @return the duration of this field, or UnsupportedDurationField if field
459 * has no duration
460 */
461 public abstract DurationField getDurationField();
462
463 /**
464 * Returns the range duration of this field. For example, if this field
465 * represents "hour of day", then the range duration is a day.
466 *
467 * @return the range duration of this field, or null if field has no range
468 */
469 public abstract DurationField getRangeDurationField();
470
471 /**
472 * Returns whether this field is 'leap' for the specified instant.
473 * <p>
474 * For example, a leap year would return true, a non leap year would return
475 * false.
476 *
477 * @param instant the instant to check for leap status
478 * @return true if the field is 'leap'
479 */
480 public abstract boolean isLeap(long instant);
481
482 /**
483 * Gets the amount by which this field is 'leap' for the specified instant.
484 * <p>
485 * For example, a leap year would return one, a non leap year would return
486 * zero.
487 *
488 * @param instant the instant to check for leap status
489 * @return the amount, in units of the leap duration field, that the field is leap
490 */
491 public abstract int getLeapAmount(long instant);
492
493 /**
494 * If this field were to leap, then it would be in units described by the
495 * returned duration. If this field doesn't ever leap, null is returned.
496 *
497 * @return the leap duration field if field can be leap, null if it can't
498 */
499 public abstract DurationField getLeapDurationField();
500
501 /**
502 * Get the minimum allowable value for this field.
503 *
504 * @return the minimum valid value for this field, in the units of the
505 * field
506 */
507 public abstract int getMinimumValue();
508
509 /**
510 * Get the minimum value for this field evaluated at the specified time.
511 *
512 * @param instant the milliseconds from 1970-01-01T00:00:00Z to query
513 * @return the minimum value for this field, in the units of the field
514 */
515 public abstract int getMinimumValue(long instant);
516
517 /**
518 * Get the minimum value for this field evaluated at the specified time.
519 *
520 * @param instant the partial instant to query
521 * @return the minimum value for this field, in the units of the field
522 */
523 public abstract int getMinimumValue(ReadablePartial instant);
524
525 /**
526 * Get the minimum value for this field using the partial instant and
527 * the specified values.
528 *
529 * @param instant the partial instant to query
530 * @param values the values to use
531 * @return the minimum value for this field, in the units of the field
532 */
533 public abstract int getMinimumValue(ReadablePartial instant, int[] values);
534
535 /**
536 * Get the maximum allowable value for this field.
537 *
538 * @return the maximum valid value for this field, in the units of the
539 * field
540 */
541 public abstract int getMaximumValue();
542
543 /**
544 * Get the maximum value for this field evaluated at the specified time.
545 *
546 * @param instant the milliseconds from 1970-01-01T00:00:00Z to query
547 * @return the maximum value for this field, in the units of the field
548 */
549 public abstract int getMaximumValue(long instant);
550
551 /**
552 * Get the maximum value for this field evaluated at the specified time.
553 *
554 * @param instant the partial instant to query
555 * @return the maximum value for this field, in the units of the field
556 */
557 public abstract int getMaximumValue(ReadablePartial instant);
558
559 /**
560 * Get the maximum value for this field using the partial instant and
561 * the specified values.
562 *
563 * @param instant the partial instant to query
564 * @param values the values to use
565 * @return the maximum value for this field, in the units of the field
566 */
567 public abstract int getMaximumValue(ReadablePartial instant, int[] values);
568
569 /**
570 * Get the maximum text value for this field.
571 *
572 * @param locale the locale to use for selecting a text symbol
573 * @return the maximum text length
574 */
575 public abstract int getMaximumTextLength(Locale locale);
576
577 /**
578 * Get the maximum short text value for this field.
579 *
580 * @param locale the locale to use for selecting a text symbol
581 * @return the maximum short text length
582 */
583 public abstract int getMaximumShortTextLength(Locale locale);
584
585 // Calculation API
586 //------------------------------------------------------------------------
587 /**
588 * Round to the lowest whole unit of this field. After rounding, the value
589 * of this field and all fields of a higher magnitude are retained. The
590 * fractional millis that cannot be expressed in whole increments of this
591 * field are set to minimum.
592 * <p>
593 * For example, a datetime of 2002-11-02T23:34:56.789, rounded to the
594 * lowest whole hour is 2002-11-02T23:00:00.000.
595 *
596 * @param instant the milliseconds from 1970-01-01T00:00:00Z to round
597 * @return rounded milliseconds
598 */
599 public abstract long roundFloor(long instant);
600
601 /**
602 * Round to the highest whole unit of this field. The value of this field
603 * and all fields of a higher magnitude may be incremented in order to
604 * achieve this result. The fractional millis that cannot be expressed in
605 * whole increments of this field are set to minimum.
606 * <p>
607 * For example, a datetime of 2002-11-02T23:34:56.789, rounded to the
608 * highest whole hour is 2002-11-03T00:00:00.000.
609 *
610 * @param instant the milliseconds from 1970-01-01T00:00:00Z to round
611 * @return rounded milliseconds
612 */
613 public abstract long roundCeiling(long instant);
614
615 /**
616 * Round to the nearest whole unit of this field. If the given millisecond
617 * value is closer to the floor or is exactly halfway, this function
618 * behaves like roundFloor. If the millisecond value is closer to the
619 * ceiling, this function behaves like roundCeiling.
620 *
621 * @param instant the milliseconds from 1970-01-01T00:00:00Z to round
622 * @return rounded milliseconds
623 */
624 public abstract long roundHalfFloor(long instant);
625
626 /**
627 * Round to the nearest whole unit of this field. If the given millisecond
628 * value is closer to the floor, this function behaves like roundFloor. If
629 * the millisecond value is closer to the ceiling or is exactly halfway,
630 * this function behaves like roundCeiling.
631 *
632 * @param instant the milliseconds from 1970-01-01T00:00:00Z to round
633 * @return rounded milliseconds
634 */
635 public abstract long roundHalfCeiling(long instant);
636
637 /**
638 * Round to the nearest whole unit of this field. If the given millisecond
639 * value is closer to the floor, this function behaves like roundFloor. If
640 * the millisecond value is closer to the ceiling, this function behaves
641 * like roundCeiling.
642 * <p>
643 * If the millisecond value is exactly halfway between the floor and
644 * ceiling, the ceiling is chosen over the floor only if it makes this
645 * field's value even.
646 *
647 * @param instant the milliseconds from 1970-01-01T00:00:00Z to round
648 * @return rounded milliseconds
649 */
650 public abstract long roundHalfEven(long instant);
651
652 /**
653 * Returns the fractional duration milliseconds of this field. In other
654 * words, calling remainder returns the duration that roundFloor would
655 * subtract.
656 * <p>
657 * For example, on a datetime of 2002-11-02T23:34:56.789, the remainder by
658 * hour is 34 minutes and 56.789 seconds.
659 *
660 * @param instant the milliseconds from 1970-01-01T00:00:00Z to get the
661 * remainder
662 * @return remainder duration, in milliseconds
663 */
664 public abstract long remainder(long instant);
665
666 /**
667 * Get a suitable debug string.
668 *
669 * @return debug string
670 */
671 public abstract String toString();
672
673 }