View Javadoc

1   /*
2    *  Copyright 2001-2011 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 volatile long iMillis;
52      /** The chronology to use */
53      private volatile 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 }