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.base;
017:
018: import java.io.Serializable;
019:
020: import org.joda.time.Chronology;
021: import org.joda.time.DateTimeUtils;
022: import org.joda.time.DateTimeZone;
023: import org.joda.time.ReadableDateTime;
024: import org.joda.time.chrono.ISOChronology;
025: import org.joda.time.convert.ConverterManager;
026: import org.joda.time.convert.InstantConverter;
027:
028: /**
029: * BaseDateTime is an abstract implementation of ReadableDateTime that stores
030: * data in <code>long</code> and <code>Chronology</code> fields.
031: * <p>
032: * This class should generally not be used directly by API users.
033: * The {@link ReadableDateTime} interface should be used when different
034: * kinds of date/time objects are to be referenced.
035: * <p>
036: * BaseDateTime subclasses may be mutable and not thread-safe.
037: *
038: * @author Stephen Colebourne
039: * @author Kandarp Shah
040: * @author Brian S O'Neill
041: * @since 1.0
042: */
043: public abstract class BaseDateTime extends AbstractDateTime implements
044: ReadableDateTime, Serializable {
045:
046: /** Serialization lock */
047: private static final long serialVersionUID = -6728882245981L;
048:
049: /** The millis from 1970-01-01T00:00:00Z */
050: private long iMillis;
051: /** The chronology to use */
052: private Chronology iChronology;
053:
054: //-----------------------------------------------------------------------
055: /**
056: * Constructs an instance set to the current system millisecond time
057: * using <code>ISOChronology</code> in the default time zone.
058: */
059: public BaseDateTime() {
060: this (DateTimeUtils.currentTimeMillis(), ISOChronology
061: .getInstance());
062: }
063:
064: /**
065: * Constructs an instance set to the current system millisecond time
066: * using <code>ISOChronology</code> in the specified time zone.
067: * <p>
068: * If the specified time zone is null, the default zone is used.
069: *
070: * @param zone the time zone, null means default zone
071: */
072: public BaseDateTime(DateTimeZone zone) {
073: this (DateTimeUtils.currentTimeMillis(), ISOChronology
074: .getInstance(zone));
075: }
076:
077: /**
078: * Constructs an instance set to the current system millisecond time
079: * using the specified chronology.
080: * <p>
081: * If the chronology is null, <code>ISOChronology</code>
082: * in the default time zone is used.
083: *
084: * @param chronology the chronology, null means ISOChronology in default zone
085: */
086: public BaseDateTime(Chronology chronology) {
087: this (DateTimeUtils.currentTimeMillis(), chronology);
088: }
089:
090: //-----------------------------------------------------------------------
091: /**
092: * Constructs an instance set to the milliseconds from 1970-01-01T00:00:00Z
093: * using <code>ISOChronology</code> in the default time zone.
094: *
095: * @param instant the milliseconds from 1970-01-01T00:00:00Z
096: */
097: public BaseDateTime(long instant) {
098: this (instant, ISOChronology.getInstance());
099: }
100:
101: /**
102: * Constructs an instance set to the milliseconds from 1970-01-01T00:00:00Z
103: * using <code>ISOChronology</code> in the specified time zone.
104: * <p>
105: * If the specified time zone is null, the default zone is used.
106: *
107: * @param instant the milliseconds from 1970-01-01T00:00:00Z
108: * @param zone the time zone, null means default zone
109: */
110: public BaseDateTime(long instant, DateTimeZone zone) {
111: this (instant, ISOChronology.getInstance(zone));
112: }
113:
114: /**
115: * Constructs an instance set to the milliseconds from 1970-01-01T00:00:00Z
116: * using the specified chronology.
117: * <p>
118: * If the chronology is null, <code>ISOChronology</code>
119: * in the default time zone is used.
120: *
121: * @param instant the milliseconds from 1970-01-01T00:00:00Z
122: * @param chronology the chronology, null means ISOChronology in default zone
123: */
124: public BaseDateTime(long instant, Chronology chronology) {
125: super ();
126: iChronology = checkChronology(chronology);
127: iMillis = checkInstant(instant, iChronology);
128: }
129:
130: //-----------------------------------------------------------------------
131: /**
132: * Constructs an instance from an Object that represents a datetime,
133: * forcing the time zone to that specified.
134: * <p>
135: * If the object contains no chronology, <code>ISOChronology</code> is used.
136: * If the specified time zone is null, the default zone is used.
137: * <p>
138: * The recognised object types are defined in
139: * {@link org.joda.time.convert.ConverterManager ConverterManager} and
140: * include ReadableInstant, String, Calendar and Date.
141: *
142: * @param instant the datetime object
143: * @param zone the time zone
144: * @throws IllegalArgumentException if the instant is invalid
145: */
146: public BaseDateTime(Object instant, DateTimeZone zone) {
147: super ();
148: InstantConverter converter = ConverterManager.getInstance()
149: .getInstantConverter(instant);
150: Chronology chrono = checkChronology(converter.getChronology(
151: instant, zone));
152: iChronology = chrono;
153: iMillis = checkInstant(converter.getInstantMillis(instant,
154: chrono), chrono);
155: }
156:
157: /**
158: * Constructs an instance from an Object that represents a datetime,
159: * using the specified chronology.
160: * <p>
161: * If the chronology is null, ISO in the default time zone is used.
162: * <p>
163: * The recognised object types are defined in
164: * {@link org.joda.time.convert.ConverterManager ConverterManager} and
165: * include ReadableInstant, String, Calendar and Date.
166: *
167: * @param instant the datetime object
168: * @param chronology the chronology
169: * @throws IllegalArgumentException if the instant is invalid
170: */
171: public BaseDateTime(Object instant, Chronology chronology) {
172: super ();
173: InstantConverter converter = ConverterManager.getInstance()
174: .getInstantConverter(instant);
175: iChronology = checkChronology(converter.getChronology(instant,
176: chronology));
177: iMillis = checkInstant(converter.getInstantMillis(instant,
178: chronology), iChronology);
179: }
180:
181: //-----------------------------------------------------------------------
182: /**
183: * Constructs an instance from datetime field values
184: * using <code>ISOChronology</code> in the default time zone.
185: *
186: * @param year the year
187: * @param monthOfYear the month of the year
188: * @param dayOfMonth the day of the month
189: * @param hourOfDay the hour of the day
190: * @param minuteOfHour the minute of the hour
191: * @param secondOfMinute the second of the minute
192: * @param millisOfSecond the millisecond of the second
193: */
194: public BaseDateTime(int year, int monthOfYear, int dayOfMonth,
195: int hourOfDay, int minuteOfHour, int secondOfMinute,
196: int millisOfSecond) {
197: this (year, monthOfYear, dayOfMonth, hourOfDay, minuteOfHour,
198: secondOfMinute, millisOfSecond, ISOChronology
199: .getInstance());
200: }
201:
202: /**
203: * Constructs an instance from datetime field values
204: * using <code>ISOChronology</code> in the specified time zone.
205: * <p>
206: * If the specified time zone is null, the default zone is used.
207: *
208: * @param year the year
209: * @param monthOfYear the month of the year
210: * @param dayOfMonth the day of the month
211: * @param hourOfDay the hour of the day
212: * @param minuteOfHour the minute of the hour
213: * @param secondOfMinute the second of the minute
214: * @param millisOfSecond the millisecond of the second
215: * @param zone the time zone, null means default time zone
216: */
217: public BaseDateTime(int year, int monthOfYear, int dayOfMonth,
218: int hourOfDay, int minuteOfHour, int secondOfMinute,
219: int millisOfSecond, DateTimeZone zone) {
220: this (year, monthOfYear, dayOfMonth, hourOfDay, minuteOfHour,
221: secondOfMinute, millisOfSecond, ISOChronology
222: .getInstance(zone));
223: }
224:
225: /**
226: * Constructs an instance from datetime field values
227: * using the specified chronology.
228: * <p>
229: * If the chronology is null, <code>ISOChronology</code>
230: * in the default time zone is used.
231: *
232: * @param year the year
233: * @param monthOfYear the month of the year
234: * @param dayOfMonth the day of the month
235: * @param hourOfDay the hour of the day
236: * @param minuteOfHour the minute of the hour
237: * @param secondOfMinute the second of the minute
238: * @param millisOfSecond the millisecond of the second
239: * @param chronology the chronology, null means ISOChronology in default zone
240: */
241: public BaseDateTime(int year, int monthOfYear, int dayOfMonth,
242: int hourOfDay, int minuteOfHour, int secondOfMinute,
243: int millisOfSecond, Chronology chronology) {
244: super ();
245: iChronology = checkChronology(chronology);
246: long instant = iChronology.getDateTimeMillis(year, monthOfYear,
247: dayOfMonth, hourOfDay, minuteOfHour, secondOfMinute,
248: millisOfSecond);
249: iMillis = checkInstant(instant, iChronology);
250: }
251:
252: //-----------------------------------------------------------------------
253: /**
254: * Checks the specified chronology before storing it, potentially altering it.
255: * This method must not access any instance variables.
256: * <p>
257: * This implementation converts nulls to ISOChronology in the default zone.
258: *
259: * @param chronology the chronology to use, may be null
260: * @return the chronology to store in this datetime, not null
261: */
262: protected Chronology checkChronology(Chronology chronology) {
263: return DateTimeUtils.getChronology(chronology);
264: }
265:
266: /**
267: * Checks the specified instant before storing it, potentially altering it.
268: * This method must not access any instance variables.
269: * <p>
270: * This implementation simply returns the instant.
271: *
272: * @param instant the milliseconds from 1970-01-01T00:00:00Z to round
273: * @param chronology the chronology to use, not null
274: * @return the instant to store in this datetime
275: */
276: protected long checkInstant(long instant, Chronology chronology) {
277: return instant;
278: }
279:
280: //-----------------------------------------------------------------------
281: /**
282: * Gets the milliseconds of the datetime instant from the Java epoch
283: * of 1970-01-01T00:00:00Z.
284: *
285: * @return the number of milliseconds since 1970-01-01T00:00:00Z
286: */
287: public long getMillis() {
288: return iMillis;
289: }
290:
291: /**
292: * Gets the chronology of the datetime.
293: *
294: * @return the Chronology that the datetime is using
295: */
296: public Chronology getChronology() {
297: return iChronology;
298: }
299:
300: //-----------------------------------------------------------------------
301: /**
302: * Sets the milliseconds of the datetime.
303: * <p>
304: * All changes to the millisecond field occurs via this method.
305: * Override and block this method to make a subclass immutable.
306: *
307: * @param instant the milliseconds since 1970-01-01T00:00:00Z to set the datetime to
308: */
309: protected void setMillis(long instant) {
310: iMillis = checkInstant(instant, iChronology);
311: }
312:
313: /**
314: * Sets the chronology of the datetime.
315: * <p>
316: * All changes to the chronology field occurs via this method.
317: * Override and block this method to make a subclass immutable.
318: *
319: * @param chronology the chronology to set
320: */
321: protected void setChronology(Chronology chronology) {
322: iChronology = checkChronology(chronology);
323: }
324:
325: }
|