1 /*
2 * Copyright 2001-2005 Stephen Colebourne
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.joda.time;
17
18 /**
19 * Defines a time period specified in terms of individual duration fields
20 * such as years and days.
21 * <p>
22 * The implementation of this interface may be mutable or immutable. This
23 * interface only gives access to retrieve data, never to change it.
24 * <p>
25 * Periods are split up into multiple fields, for example days and seconds.
26 * Implementations are not required to evenly distribute the values across the fields.
27 * The value for each field may be positive or negative.
28 * <p>
29 * When a time period is added to an instant, the effect is to add each field in turn.
30 * For example, a time period could be defined as 3 months, 2 days and -1 hours.
31 * In most circumstances this would be the same as 3 months, 1 day, and 23 hours.
32 * However, when adding across a daylight savings boundary, a day may be 23 or 25 hours long.
33 * Thus, the time period is always added field by field to the datetime.
34 * <p>
35 * Periods are independent of chronology, and can only be treated as durations
36 * when paired with a time via an interval.
37 *
38 * @see ReadableDuration
39 * @see ReadableInterval
40 * @author Brian S O'Neill
41 * @author Stephen Colebourne
42 * @since 1.0
43 */
44 public interface ReadablePeriod {
45
46 /**
47 * Gets the period type that defines which fields are included in the period.
48 *
49 * @return the period type
50 */
51 PeriodType getPeriodType();
52
53 /**
54 * Gets the number of fields that this period supports.
55 *
56 * @return the number of fields supported
57 */
58 int size();
59
60 /**
61 * Gets the field type at the specified index.
62 *
63 * @param index the index to retrieve
64 * @return the field at the specified index
65 * @throws IndexOutOfBoundsException if the index is invalid
66 */
67 DurationFieldType getFieldType(int index);
68
69 /**
70 * Gets the value at the specified index.
71 *
72 * @param index the index to retrieve
73 * @return the value of the field at the specified index
74 * @throws IndexOutOfBoundsException if the index is invalid
75 */
76 int getValue(int index);
77
78 /**
79 * Gets the value of one of the fields.
80 * <p>
81 * If the field type specified is not supported by the period then zero
82 * is returned.
83 *
84 * @param field the field type to query, null returns zero
85 * @return the value of that field, zero if field not supported
86 */
87 int get(DurationFieldType field);
88
89 /**
90 * Checks whether the field type specified is supported by this period.
91 *
92 * @param field the field to check, may be null which returns false
93 * @return true if the field is supported
94 */
95 boolean isSupported(DurationFieldType field);
96
97 //-----------------------------------------------------------------------
98 /**
99 * Get this period as an immutable <code>Period</code> object.
100 * <p>
101 * This will either typecast this instance, or create a new <code>Period</code>.
102 *
103 * @return a Duration using the same field set and values
104 */
105 Period toPeriod();
106
107 /**
108 * Get this object as a <code>MutablePeriod</code>.
109 * <p>
110 * This will always return a new <code>MutablePeriod</code> with the same fields.
111 *
112 * @return a MutablePeriod using the same field set and values
113 */
114 MutablePeriod toMutablePeriod();
115
116 //-----------------------------------------------------------------------
117 /**
118 * Compares this object with the specified object for equality based
119 * on the value and type of each supported field.
120 * All ReadablePeriod instances are accepted.
121 * <p>
122 * Note that a period of 1 day is not equal to a period of 24 hours,
123 * nor is 1 hour equal to 60 minutes. Only periods with the same amount
124 * in each field are equal.
125 * <p>
126 * This is because periods represent an abstracted definition of a time
127 * period (eg. a day may not actually be 24 hours, it might be 23 or 25
128 * at daylight savings boundary).
129 * <p>
130 * To compare the actual duration of two periods, convert both to
131 * {@link Duration}s, an operation that emphasises that the result may
132 * differ according to the date you choose.
133 *
134 * @param readablePeriod a readable period to check against
135 * @return true if all the field values and types are equal, false if
136 * not or the period is null or of an incorrect type
137 */
138 boolean equals(Object readablePeriod);
139
140 /**
141 * Gets a hash code for the period that is compatible with the equals method.
142 * The hashcode is calculated as follows:
143 * <pre>
144 * int total = 17;
145 * for (int i = 0; i < fields.length; i++) {
146 * total = 27 * total + getValue(i);
147 * total = 27 * total + getFieldType(i).hashCode();
148 * }
149 * return total;
150 * </pre>
151 *
152 * @return a hash code
153 */
154 int hashCode();
155
156 //-----------------------------------------------------------------------
157 /**
158 * Gets the value as a String in the style of the ISO8601 duration format.
159 * Technically, the output can breach the ISO specification as weeks may be included.
160 * <p>
161 * For example, "PT6H3M5S" represents 6 hours, 3 minutes, 5 seconds.
162 *
163 * @return the value as an ISO8601 style string
164 */
165 String toString();
166
167 }