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 */
016package org.joda.time.base;
017
018import java.util.Calendar;
019import java.util.GregorianCalendar;
020import java.util.Locale;
021
022import org.joda.time.DateTimeFieldType;
023import org.joda.time.DateTimeZone;
024import org.joda.time.ReadableDateTime;
025import org.joda.time.format.DateTimeFormat;
026
027/**
028 * AbstractDateTime provides the common behaviour for datetime classes.
029 * <p>
030 * This class should generally not be used directly by API users.
031 * The {@link ReadableDateTime} interface should be used when different 
032 * kinds of date/time objects are to be referenced.
033 * <p>
034 * Whenever you want to implement <code>ReadableDateTime</code> you should
035 * extend this class.
036 * <p>
037 * AbstractDateTime subclasses may be mutable and not thread-safe.
038 *
039 * @author Brian S O'Neill
040 * @author Stephen Colebourne
041 * @since 1.0
042 */
043public abstract class AbstractDateTime
044        extends AbstractInstant
045        implements ReadableDateTime {
046
047    /**
048     * Constructor.
049     */
050    protected AbstractDateTime() {
051        super();
052    }
053
054    //-----------------------------------------------------------------------
055    /**
056     * Get the value of one of the fields of a datetime.
057     * <p>
058     * This method uses the chronology of the datetime to obtain the value.
059     * It is essentially a generic way of calling one of the get methods.
060     *
061     * @param type  a field type, usually obtained from DateTimeFieldType
062     * @return the value of that field
063     * @throws IllegalArgumentException if the field type is null
064     */
065    public int get(DateTimeFieldType type) {
066        if (type == null) {
067            throw new IllegalArgumentException("The DateTimeFieldType must not be null");
068        }
069        return type.getField(getChronology()).get(getMillis());
070    }
071
072    //-----------------------------------------------------------------------
073    /**
074     * Get the era field value.
075     * 
076     * @return the era
077     */
078    public int getEra() {
079        return getChronology().era().get(getMillis());
080    }
081
082    /**
083     * Get the year of era field value.
084     * 
085     * @return the year of era
086     */
087    public int getCenturyOfEra() {
088        return getChronology().centuryOfEra().get(getMillis());
089    }
090
091    /**
092     * Get the year of era field value.
093     * 
094     * @return the year of era
095     */
096    public int getYearOfEra() {
097        return getChronology().yearOfEra().get(getMillis());
098    }
099
100    /**
101     * Get the year of century field value.
102     * 
103     * @return the year of century
104     */
105    public int getYearOfCentury() {
106        return getChronology().yearOfCentury().get(getMillis());
107    }
108
109    /**
110     * Get the year field value.
111     * 
112     * @return the year
113     */
114    public int getYear() {
115        return getChronology().year().get(getMillis());
116    }
117
118    /**
119     * Get the weekyear field value.
120     * 
121     * @return the year of a week based year
122     */
123    public int getWeekyear() {
124        return getChronology().weekyear().get(getMillis());
125    }
126
127    /**
128     * Get the month of year field value.
129     * 
130     * @return the month of year
131     */
132    public int getMonthOfYear() {
133        return getChronology().monthOfYear().get(getMillis());
134    }
135
136    /**
137     * Get the week of weekyear field value.
138     * 
139     * @return the week of a week based year
140     */
141    public int getWeekOfWeekyear() {
142        return getChronology().weekOfWeekyear().get(getMillis());
143    }
144
145    /**
146     * Get the day of year field value.
147     * 
148     * @return the day of year
149     */
150    public int getDayOfYear() {
151        return getChronology().dayOfYear().get(getMillis());
152    }
153
154    /**
155     * Get the day of month field value.
156     * <p>
157     * The values for the day of month are defined in {@link org.joda.time.DateTimeConstants}.
158     * 
159     * @return the day of month
160     */
161    public int getDayOfMonth() {
162        return getChronology().dayOfMonth().get(getMillis());
163    }
164
165    /**
166     * Get the day of week field value.
167     * <p>
168     * The values for the day of week are defined in {@link org.joda.time.DateTimeConstants}.
169     * 
170     * @return the day of week
171     */
172    public int getDayOfWeek() {
173        return getChronology().dayOfWeek().get(getMillis());
174    }
175
176    //-----------------------------------------------------------------------
177    /**
178     * Get the hour of day field value.
179     *
180     * @return the hour of day
181     */
182    public int getHourOfDay() {
183        return getChronology().hourOfDay().get(getMillis());
184    }
185
186    /**
187     * Get the minute of day field value.
188     *
189     * @return the minute of day
190     */
191    public int getMinuteOfDay() {
192        return getChronology().minuteOfDay().get(getMillis());
193    }
194
195    /**
196     * Get the minute of hour field value.
197     *
198     * @return the minute of hour
199     */
200    public int getMinuteOfHour() {
201        return getChronology().minuteOfHour().get(getMillis());
202    }
203
204    /**
205     * Get the second of day field value.
206     *
207     * @return the second of day
208     */
209    public int getSecondOfDay() {
210        return getChronology().secondOfDay().get(getMillis());
211    }
212
213    /**
214     * Get the second of minute field value.
215     *
216     * @return the second of minute
217     */
218    public int getSecondOfMinute() {
219        return getChronology().secondOfMinute().get(getMillis());
220    }
221
222    /**
223     * Get the millis of day field value.
224     *
225     * @return the millis of day
226     */
227    public int getMillisOfDay() {
228        return getChronology().millisOfDay().get(getMillis());
229    }
230
231    /**
232     * Get the millis of second field value.
233     *
234     * @return the millis of second
235     */
236    public int getMillisOfSecond() {
237        return getChronology().millisOfSecond().get(getMillis());
238    }
239
240    //-----------------------------------------------------------------------
241    /**
242     * Get the date time as a <code>java.util.Calendar</code>, assigning
243     * exactly the same millisecond instant.
244     * The locale is passed in, enabling Calendar to select the correct
245     * localized subclass.
246     * <p>
247     * The JDK and Joda-Time both have time zone implementations and these
248     * differ in accuracy. Joda-Time's implementation is generally more up to
249     * date and thus more accurate - for example JDK1.3 has no historical data.
250     * The effect of this is that the field values of the <code>Calendar</code>
251     * may differ from those of this object, even though the milliseond value
252     * is the same. Most of the time this just means that the JDK field values
253     * are wrong, as our time zone information is more up to date.
254     *
255     * @param locale  the locale to get the Calendar for, or default if null
256     * @return a localized Calendar initialised with this datetime
257     */
258    public Calendar toCalendar(Locale locale) {
259        if (locale == null) {
260            locale = Locale.getDefault();
261        }
262        DateTimeZone zone = getZone();
263        Calendar cal = Calendar.getInstance(zone.toTimeZone(), locale);
264        cal.setTime(toDate());
265        return cal;
266    }
267
268    /**
269     * Get the date time as a <code>java.util.GregorianCalendar</code>,
270     * assigning exactly the same millisecond instant.
271     * <p>
272     * The JDK and Joda-Time both have time zone implementations and these
273     * differ in accuracy. Joda-Time's implementation is generally more up to
274     * date and thus more accurate - for example JDK1.3 has no historical data.
275     * The effect of this is that the field values of the <code>Calendar</code>
276     * may differ from those of this object, even though the milliseond value
277     * is the same. Most of the time this just means that the JDK field values
278     * are wrong, as our time zone information is more up to date.
279     *
280     * @return a GregorianCalendar initialised with this datetime
281     */
282    public GregorianCalendar toGregorianCalendar() {
283        DateTimeZone zone = getZone();
284        GregorianCalendar cal = new GregorianCalendar(zone.toTimeZone());
285        cal.setTime(toDate());
286        return cal;
287    }
288
289    //-----------------------------------------------------------------------
290    /**
291     * Output the instant using the specified format pattern.
292     *
293     * @param pattern  the pattern specification, null means use <code>toString</code>
294     * @see  org.joda.time.format.DateTimeFormat
295     */
296    public String toString(String pattern) {
297        if (pattern == null) {
298            return toString();
299        }
300        return DateTimeFormat.forPattern(pattern).print(this);
301    }
302
303    /**
304     * Output the instant using the specified format pattern.
305     *
306     * @param pattern  the pattern specification, null means use <code>toString</code>
307     * @param locale  Locale to use, null means default
308     * @see  org.joda.time.format.DateTimeFormat
309     */
310    public String toString(String pattern, Locale locale) throws IllegalArgumentException {
311        if (pattern == null) {
312            return toString();
313        }
314        return DateTimeFormat.forPattern(pattern).withLocale(locale).print(this);
315    }
316
317}