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.base; |
17 | |
18 | import java.io.Serializable; |
19 | |
20 | import org.joda.time.Chronology; |
21 | import org.joda.time.DateTimeUtils; |
22 | import org.joda.time.DateTimeZone; |
23 | import org.joda.time.ReadableDateTime; |
24 | import org.joda.time.chrono.ISOChronology; |
25 | import org.joda.time.convert.ConverterManager; |
26 | import org.joda.time.convert.InstantConverter; |
27 | |
28 | /** |
29 | * BaseDateTime is an abstract implementation of ReadableDateTime that stores |
30 | * data in <code>long</code> and <code>Chronology</code> fields. |
31 | * <p> |
32 | * This class should generally not be used directly by API users. |
33 | * The {@link ReadableDateTime} interface should be used when different |
34 | * kinds of date/time objects are to be referenced. |
35 | * <p> |
36 | * BaseDateTime subclasses may be mutable and not thread-safe. |
37 | * |
38 | * @author Stephen Colebourne |
39 | * @author Kandarp Shah |
40 | * @author Brian S O'Neill |
41 | * @since 1.0 |
42 | */ |
43 | public abstract class BaseDateTime |
44 | extends AbstractDateTime |
45 | implements ReadableDateTime, Serializable { |
46 | |
47 | /** Serialization lock */ |
48 | private static final long serialVersionUID = -6728882245981L; |
49 | |
50 | /** The millis from 1970-01-01T00:00:00Z */ |
51 | private long iMillis; |
52 | /** The chronology to use */ |
53 | private Chronology iChronology; |
54 | |
55 | //----------------------------------------------------------------------- |
56 | /** |
57 | * Constructs an instance set to the current system millisecond time |
58 | * using <code>ISOChronology</code> in the default time zone. |
59 | */ |
60 | public BaseDateTime() { |
61 | this(DateTimeUtils.currentTimeMillis(), ISOChronology.getInstance()); |
62 | } |
63 | |
64 | /** |
65 | * Constructs an instance set to the current system millisecond time |
66 | * using <code>ISOChronology</code> in the specified time zone. |
67 | * <p> |
68 | * If the specified time zone is null, the default zone is used. |
69 | * |
70 | * @param zone the time zone, null means default zone |
71 | */ |
72 | public BaseDateTime(DateTimeZone zone) { |
73 | this(DateTimeUtils.currentTimeMillis(), ISOChronology.getInstance(zone)); |
74 | } |
75 | |
76 | /** |
77 | * Constructs an instance set to the current system millisecond time |
78 | * using the specified chronology. |
79 | * <p> |
80 | * If the chronology is null, <code>ISOChronology</code> |
81 | * in the default time zone is used. |
82 | * |
83 | * @param chronology the chronology, null means ISOChronology in default zone |
84 | */ |
85 | public BaseDateTime(Chronology chronology) { |
86 | this(DateTimeUtils.currentTimeMillis(), chronology); |
87 | } |
88 | |
89 | //----------------------------------------------------------------------- |
90 | /** |
91 | * Constructs an instance set to the milliseconds from 1970-01-01T00:00:00Z |
92 | * using <code>ISOChronology</code> in the default time zone. |
93 | * |
94 | * @param instant the milliseconds from 1970-01-01T00:00:00Z |
95 | */ |
96 | public BaseDateTime(long instant) { |
97 | this(instant, ISOChronology.getInstance()); |
98 | } |
99 | |
100 | /** |
101 | * Constructs an instance set to the milliseconds from 1970-01-01T00:00:00Z |
102 | * using <code>ISOChronology</code> in the specified time zone. |
103 | * <p> |
104 | * If the specified time zone is null, the default zone is used. |
105 | * |
106 | * @param instant the milliseconds from 1970-01-01T00:00:00Z |
107 | * @param zone the time zone, null means default zone |
108 | */ |
109 | public BaseDateTime(long instant, DateTimeZone zone) { |
110 | this(instant, ISOChronology.getInstance(zone)); |
111 | } |
112 | |
113 | /** |
114 | * Constructs an instance set to the milliseconds from 1970-01-01T00:00:00Z |
115 | * using the specified chronology. |
116 | * <p> |
117 | * If the chronology is null, <code>ISOChronology</code> |
118 | * in the default time zone is used. |
119 | * |
120 | * @param instant the milliseconds from 1970-01-01T00:00:00Z |
121 | * @param chronology the chronology, null means ISOChronology in default zone |
122 | */ |
123 | public BaseDateTime(long instant, Chronology chronology) { |
124 | super(); |
125 | iChronology = checkChronology(chronology); |
126 | iMillis = checkInstant(instant, iChronology); |
127 | } |
128 | |
129 | //----------------------------------------------------------------------- |
130 | /** |
131 | * Constructs an instance from an Object that represents a datetime, |
132 | * forcing the time zone to that specified. |
133 | * <p> |
134 | * If the object contains no chronology, <code>ISOChronology</code> is used. |
135 | * If the specified time zone is null, the default zone is used. |
136 | * <p> |
137 | * The recognised object types are defined in |
138 | * {@link org.joda.time.convert.ConverterManager ConverterManager} and |
139 | * include ReadableInstant, String, Calendar and Date. |
140 | * |
141 | * @param instant the datetime object |
142 | * @param zone the time zone |
143 | * @throws IllegalArgumentException if the instant is invalid |
144 | */ |
145 | public BaseDateTime(Object instant, DateTimeZone zone) { |
146 | super(); |
147 | InstantConverter converter = ConverterManager.getInstance().getInstantConverter(instant); |
148 | Chronology chrono = checkChronology(converter.getChronology(instant, zone)); |
149 | iChronology = chrono; |
150 | iMillis = checkInstant(converter.getInstantMillis(instant, chrono), chrono); |
151 | } |
152 | |
153 | /** |
154 | * Constructs an instance from an Object that represents a datetime, |
155 | * using the specified chronology. |
156 | * <p> |
157 | * If the chronology is null, ISO in the default time zone is used. |
158 | * <p> |
159 | * The recognised object types are defined in |
160 | * {@link org.joda.time.convert.ConverterManager ConverterManager} and |
161 | * include ReadableInstant, String, Calendar and Date. |
162 | * |
163 | * @param instant the datetime object |
164 | * @param chronology the chronology |
165 | * @throws IllegalArgumentException if the instant is invalid |
166 | */ |
167 | public BaseDateTime(Object instant, Chronology chronology) { |
168 | super(); |
169 | InstantConverter converter = ConverterManager.getInstance().getInstantConverter(instant); |
170 | iChronology = checkChronology(converter.getChronology(instant, chronology)); |
171 | iMillis = checkInstant(converter.getInstantMillis(instant, chronology), iChronology); |
172 | } |
173 | |
174 | //----------------------------------------------------------------------- |
175 | /** |
176 | * Constructs an instance from datetime field values |
177 | * using <code>ISOChronology</code> in the default time zone. |
178 | * |
179 | * @param year the year |
180 | * @param monthOfYear the month of the year |
181 | * @param dayOfMonth the day of the month |
182 | * @param hourOfDay the hour of the day |
183 | * @param minuteOfHour the minute of the hour |
184 | * @param secondOfMinute the second of the minute |
185 | * @param millisOfSecond the millisecond of the second |
186 | */ |
187 | public BaseDateTime( |
188 | int year, |
189 | int monthOfYear, |
190 | int dayOfMonth, |
191 | int hourOfDay, |
192 | int minuteOfHour, |
193 | int secondOfMinute, |
194 | int millisOfSecond) { |
195 | this(year, monthOfYear, dayOfMonth, hourOfDay, |
196 | minuteOfHour, secondOfMinute, millisOfSecond, ISOChronology.getInstance()); |
197 | } |
198 | |
199 | /** |
200 | * Constructs an instance from datetime field values |
201 | * using <code>ISOChronology</code> in the specified time zone. |
202 | * <p> |
203 | * If the specified time zone is null, the default zone is used. |
204 | * |
205 | * @param year the year |
206 | * @param monthOfYear the month of the year |
207 | * @param dayOfMonth the day of the month |
208 | * @param hourOfDay the hour of the day |
209 | * @param minuteOfHour the minute of the hour |
210 | * @param secondOfMinute the second of the minute |
211 | * @param millisOfSecond the millisecond of the second |
212 | * @param zone the time zone, null means default time zone |
213 | */ |
214 | public BaseDateTime( |
215 | int year, |
216 | int monthOfYear, |
217 | int dayOfMonth, |
218 | int hourOfDay, |
219 | int minuteOfHour, |
220 | int secondOfMinute, |
221 | int millisOfSecond, |
222 | DateTimeZone zone) { |
223 | this(year, monthOfYear, dayOfMonth, hourOfDay, |
224 | minuteOfHour, secondOfMinute, millisOfSecond, ISOChronology.getInstance(zone)); |
225 | } |
226 | |
227 | /** |
228 | * Constructs an instance from datetime field values |
229 | * using the specified chronology. |
230 | * <p> |
231 | * If the chronology is null, <code>ISOChronology</code> |
232 | * in the default time zone is used. |
233 | * |
234 | * @param year the year |
235 | * @param monthOfYear the month of the year |
236 | * @param dayOfMonth the day of the month |
237 | * @param hourOfDay the hour of the day |
238 | * @param minuteOfHour the minute of the hour |
239 | * @param secondOfMinute the second of the minute |
240 | * @param millisOfSecond the millisecond of the second |
241 | * @param chronology the chronology, null means ISOChronology in default zone |
242 | */ |
243 | public BaseDateTime( |
244 | int year, |
245 | int monthOfYear, |
246 | int dayOfMonth, |
247 | int hourOfDay, |
248 | int minuteOfHour, |
249 | int secondOfMinute, |
250 | int millisOfSecond, |
251 | Chronology chronology) { |
252 | super(); |
253 | iChronology = checkChronology(chronology); |
254 | long instant = iChronology.getDateTimeMillis(year, monthOfYear, dayOfMonth, |
255 | hourOfDay, minuteOfHour, secondOfMinute, millisOfSecond); |
256 | iMillis = checkInstant(instant, iChronology); |
257 | } |
258 | |
259 | //----------------------------------------------------------------------- |
260 | /** |
261 | * Checks the specified chronology before storing it, potentially altering it. |
262 | * This method must not access any instance variables. |
263 | * <p> |
264 | * This implementation converts nulls to ISOChronology in the default zone. |
265 | * |
266 | * @param chronology the chronology to use, may be null |
267 | * @return the chronology to store in this datetime, not null |
268 | */ |
269 | protected Chronology checkChronology(Chronology chronology) { |
270 | return DateTimeUtils.getChronology(chronology); |
271 | } |
272 | |
273 | /** |
274 | * Checks the specified instant before storing it, potentially altering it. |
275 | * This method must not access any instance variables. |
276 | * <p> |
277 | * This implementation simply returns the instant. |
278 | * |
279 | * @param instant the milliseconds from 1970-01-01T00:00:00Z to round |
280 | * @param chronology the chronology to use, not null |
281 | * @return the instant to store in this datetime |
282 | */ |
283 | protected long checkInstant(long instant, Chronology chronology) { |
284 | return instant; |
285 | } |
286 | |
287 | //----------------------------------------------------------------------- |
288 | /** |
289 | * Gets the milliseconds of the datetime instant from the Java epoch |
290 | * of 1970-01-01T00:00:00Z. |
291 | * |
292 | * @return the number of milliseconds since 1970-01-01T00:00:00Z |
293 | */ |
294 | public long getMillis() { |
295 | return iMillis; |
296 | } |
297 | |
298 | /** |
299 | * Gets the chronology of the datetime. |
300 | * |
301 | * @return the Chronology that the datetime is using |
302 | */ |
303 | public Chronology getChronology() { |
304 | return iChronology; |
305 | } |
306 | |
307 | //----------------------------------------------------------------------- |
308 | /** |
309 | * Sets the milliseconds of the datetime. |
310 | * <p> |
311 | * All changes to the millisecond field occurs via this method. |
312 | * Override and block this method to make a subclass immutable. |
313 | * |
314 | * @param instant the milliseconds since 1970-01-01T00:00:00Z to set the datetime to |
315 | */ |
316 | protected void setMillis(long instant) { |
317 | iMillis = checkInstant(instant, iChronology); |
318 | } |
319 | |
320 | /** |
321 | * Sets the chronology of the datetime. |
322 | * <p> |
323 | * All changes to the chronology field occurs via this method. |
324 | * Override and block this method to make a subclass immutable. |
325 | * |
326 | * @param chronology the chronology to set |
327 | */ |
328 | protected void setChronology(Chronology chronology) { |
329 | iChronology = checkChronology(chronology); |
330 | } |
331 | |
332 | } |