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 | import java.io.Serializable; |
19 | |
20 | /** |
21 | * Identifies a duration field, such as years or minutes, in a chronology-neutral way. |
22 | * <p> |
23 | * A duration field type defines the type of the field, such as hours. |
24 | * If does not directly enable any calculations, however it does provide a |
25 | * {@link #getField(Chronology)} method that returns the actual calculation engine |
26 | * for a particular chronology. |
27 | * <p> |
28 | * Instances of <code>DurationFieldType</code> are singletons. |
29 | * They can be compared using <code>==</code>. |
30 | * <p> |
31 | * If required, you can create your own field, for example a quarters. |
32 | * You must create a subclass of <code>DurationFieldType</code> that defines the field type. |
33 | * This class returns the actual calculation engine from {@link #getField(Chronology)}. |
34 | * |
35 | * @author Stephen Colebourne |
36 | * @author Brian S O'Neill |
37 | * @since 1.0 |
38 | */ |
39 | public abstract class DurationFieldType implements Serializable { |
40 | |
41 | /** Serialization version */ |
42 | private static final long serialVersionUID = 8765135187319L; |
43 | |
44 | // Ordinals for standard field types. |
45 | static final byte |
46 | ERAS = 1, |
47 | CENTURIES = 2, |
48 | WEEKYEARS = 3, |
49 | YEARS = 4, |
50 | MONTHS = 5, |
51 | WEEKS = 6, |
52 | DAYS = 7, |
53 | HALFDAYS = 8, |
54 | HOURS = 9, |
55 | MINUTES = 10, |
56 | SECONDS = 11, |
57 | MILLIS = 12; |
58 | |
59 | /** The eras field type. */ |
60 | static final DurationFieldType ERAS_TYPE = new StandardDurationFieldType("eras", ERAS); |
61 | /** The centuries field type. */ |
62 | static final DurationFieldType CENTURIES_TYPE = new StandardDurationFieldType("centuries", CENTURIES); |
63 | /** The weekyears field type. */ |
64 | static final DurationFieldType WEEKYEARS_TYPE = new StandardDurationFieldType("weekyears", WEEKYEARS); |
65 | /** The years field type. */ |
66 | static final DurationFieldType YEARS_TYPE = new StandardDurationFieldType("years", YEARS); |
67 | /** The months field type. */ |
68 | static final DurationFieldType MONTHS_TYPE = new StandardDurationFieldType("months", MONTHS); |
69 | /** The weeks field type. */ |
70 | static final DurationFieldType WEEKS_TYPE = new StandardDurationFieldType("weeks", WEEKS); |
71 | /** The days field type. */ |
72 | static final DurationFieldType DAYS_TYPE = new StandardDurationFieldType("days", DAYS); |
73 | /** The halfdays field type. */ |
74 | static final DurationFieldType HALFDAYS_TYPE = new StandardDurationFieldType("halfdays", HALFDAYS); |
75 | /** The hours field type. */ |
76 | static final DurationFieldType HOURS_TYPE = new StandardDurationFieldType("hours", HOURS); |
77 | /** The minutes field type. */ |
78 | static final DurationFieldType MINUTES_TYPE = new StandardDurationFieldType("minutes", MINUTES); |
79 | /** The seconds field type. */ |
80 | static final DurationFieldType SECONDS_TYPE = new StandardDurationFieldType("seconds", SECONDS); |
81 | /** The millis field type. */ |
82 | static final DurationFieldType MILLIS_TYPE = new StandardDurationFieldType("millis", MILLIS); |
83 | |
84 | /** The name of the field type. */ |
85 | private final String iName; |
86 | |
87 | //----------------------------------------------------------------------- |
88 | /** |
89 | * Constructor. |
90 | * |
91 | * @param name the name to use, which by convention, are plural. |
92 | */ |
93 | protected DurationFieldType(String name) { |
94 | super(); |
95 | iName = name; |
96 | } |
97 | |
98 | //----------------------------------------------------------------------- |
99 | /** |
100 | * Get the millis field type. |
101 | * |
102 | * @return the DateTimeFieldType constant |
103 | */ |
104 | public static DurationFieldType millis() { |
105 | return MILLIS_TYPE; |
106 | } |
107 | |
108 | /** |
109 | * Get the seconds field type. |
110 | * |
111 | * @return the DateTimeFieldType constant |
112 | */ |
113 | public static DurationFieldType seconds() { |
114 | return SECONDS_TYPE; |
115 | } |
116 | |
117 | /** |
118 | * Get the minutes field type. |
119 | * |
120 | * @return the DateTimeFieldType constant |
121 | */ |
122 | public static DurationFieldType minutes() { |
123 | return MINUTES_TYPE; |
124 | } |
125 | |
126 | /** |
127 | * Get the hours field type. |
128 | * |
129 | * @return the DateTimeFieldType constant |
130 | */ |
131 | public static DurationFieldType hours() { |
132 | return HOURS_TYPE; |
133 | } |
134 | |
135 | /** |
136 | * Get the halfdays field type. |
137 | * |
138 | * @return the DateTimeFieldType constant |
139 | */ |
140 | public static DurationFieldType halfdays() { |
141 | return HALFDAYS_TYPE; |
142 | } |
143 | |
144 | //----------------------------------------------------------------------- |
145 | /** |
146 | * Get the days field type. |
147 | * |
148 | * @return the DateTimeFieldType constant |
149 | */ |
150 | public static DurationFieldType days() { |
151 | return DAYS_TYPE; |
152 | } |
153 | |
154 | /** |
155 | * Get the weeks field type. |
156 | * |
157 | * @return the DateTimeFieldType constant |
158 | */ |
159 | public static DurationFieldType weeks() { |
160 | return WEEKS_TYPE; |
161 | } |
162 | |
163 | /** |
164 | * Get the weekyears field type. |
165 | * |
166 | * @return the DateTimeFieldType constant |
167 | */ |
168 | public static DurationFieldType weekyears() { |
169 | return WEEKYEARS_TYPE; |
170 | } |
171 | |
172 | /** |
173 | * Get the months field type. |
174 | * |
175 | * @return the DateTimeFieldType constant |
176 | */ |
177 | public static DurationFieldType months() { |
178 | return MONTHS_TYPE; |
179 | } |
180 | |
181 | /** |
182 | * Get the years field type. |
183 | * |
184 | * @return the DateTimeFieldType constant |
185 | */ |
186 | public static DurationFieldType years() { |
187 | return YEARS_TYPE; |
188 | } |
189 | |
190 | /** |
191 | * Get the centuries field type. |
192 | * |
193 | * @return the DateTimeFieldType constant |
194 | */ |
195 | public static DurationFieldType centuries() { |
196 | return CENTURIES_TYPE; |
197 | } |
198 | |
199 | /** |
200 | * Get the eras field type. |
201 | * |
202 | * @return the DateTimeFieldType constant |
203 | */ |
204 | public static DurationFieldType eras() { |
205 | return ERAS_TYPE; |
206 | } |
207 | |
208 | //----------------------------------------------------------------------- |
209 | /** |
210 | * Get the name of the field. |
211 | * By convention, names are plural. |
212 | * |
213 | * @return field name |
214 | */ |
215 | public String getName() { |
216 | return iName; |
217 | } |
218 | |
219 | /** |
220 | * Gets a suitable field for this type from the given Chronology. |
221 | * |
222 | * @param chronology the chronology to use, null means ISOChronology in default zone |
223 | * @return a suitable field |
224 | */ |
225 | public abstract DurationField getField(Chronology chronology); |
226 | |
227 | /** |
228 | * Checks whether this field supported in the given Chronology. |
229 | * |
230 | * @param chronology the chronology to use, null means ISOChronology in default zone |
231 | * @return true if supported |
232 | */ |
233 | public boolean isSupported(Chronology chronology) { |
234 | return getField(chronology).isSupported(); |
235 | } |
236 | |
237 | /** |
238 | * Get a suitable debug string. |
239 | * |
240 | * @return debug string |
241 | */ |
242 | public String toString() { |
243 | return getName(); |
244 | } |
245 | |
246 | private static class StandardDurationFieldType extends DurationFieldType { |
247 | /** Serialization version */ |
248 | private static final long serialVersionUID = 31156755687123L; |
249 | |
250 | /** The ordinal of the standard field type, for switch statements */ |
251 | private final byte iOrdinal; |
252 | |
253 | /** |
254 | * Constructor. |
255 | * |
256 | * @param name the name to use |
257 | */ |
258 | StandardDurationFieldType(String name, byte ordinal) { |
259 | super(name); |
260 | iOrdinal = ordinal; |
261 | } |
262 | |
263 | public DurationField getField(Chronology chronology) { |
264 | chronology = DateTimeUtils.getChronology(chronology); |
265 | |
266 | switch (iOrdinal) { |
267 | case ERAS: |
268 | return chronology.eras(); |
269 | case CENTURIES: |
270 | return chronology.centuries(); |
271 | case WEEKYEARS: |
272 | return chronology.weekyears(); |
273 | case YEARS: |
274 | return chronology.years(); |
275 | case MONTHS: |
276 | return chronology.months(); |
277 | case WEEKS: |
278 | return chronology.weeks(); |
279 | case DAYS: |
280 | return chronology.days(); |
281 | case HALFDAYS: |
282 | return chronology.halfdays(); |
283 | case HOURS: |
284 | return chronology.hours(); |
285 | case MINUTES: |
286 | return chronology.minutes(); |
287 | case SECONDS: |
288 | return chronology.seconds(); |
289 | case MILLIS: |
290 | return chronology.millis(); |
291 | default: |
292 | // Shouldn't happen. |
293 | throw new InternalError(); |
294 | } |
295 | } |
296 | |
297 | /** |
298 | * Ensure a singleton is returned. |
299 | * |
300 | * @return the singleton type |
301 | */ |
302 | private Object readResolve() { |
303 | switch (iOrdinal) { |
304 | case ERAS: |
305 | return ERAS_TYPE; |
306 | case CENTURIES: |
307 | return CENTURIES_TYPE; |
308 | case WEEKYEARS: |
309 | return WEEKYEARS_TYPE; |
310 | case YEARS: |
311 | return YEARS_TYPE; |
312 | case MONTHS: |
313 | return MONTHS_TYPE; |
314 | case WEEKS: |
315 | return WEEKS_TYPE; |
316 | case DAYS: |
317 | return DAYS_TYPE; |
318 | case HALFDAYS: |
319 | return HALFDAYS_TYPE; |
320 | case HOURS: |
321 | return HOURS_TYPE; |
322 | case MINUTES: |
323 | return MINUTES_TYPE; |
324 | case SECONDS: |
325 | return SECONDS_TYPE; |
326 | case MILLIS: |
327 | return MILLIS_TYPE; |
328 | default: |
329 | // Shouldn't happen. |
330 | return this; |
331 | } |
332 | } |
333 | |
334 | } |
335 | } |