001/*
002 *  Copyright 2001-2011 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     * <p>
121     * The weekyear is the year that matches with the weekOfWeekyear field.
122     * In the standard ISO8601 week algorithm, the first week of the year
123     * is that in which at least 4 days are in the year. As a result of this
124     * definition, day 1 of the first week may be in the previous year.
125     * The weekyear allows you to query the effective year for that day.
126     * 
127     * @return the year of a week based year
128     */
129    public int getWeekyear() {
130        return getChronology().weekyear().get(getMillis());
131    }
132
133    /**
134     * Get the month of year field value.
135     * 
136     * @return the month of year
137     */
138    public int getMonthOfYear() {
139        return getChronology().monthOfYear().get(getMillis());
140    }
141
142    /**
143     * Get the week of weekyear field value.
144     * <p>
145     * This field is associated with the "weekyear" via {@link #getWeekyear()}.
146     * In the standard ISO8601 week algorithm, the first week of the year
147     * is that in which at least 4 days are in the year. As a result of this
148     * definition, day 1 of the first week may be in the previous year.
149     * 
150     * @return the week of a week based year
151     */
152    public int getWeekOfWeekyear() {
153        return getChronology().weekOfWeekyear().get(getMillis());
154    }
155
156    /**
157     * Get the day of year field value.
158     * 
159     * @return the day of year
160     */
161    public int getDayOfYear() {
162        return getChronology().dayOfYear().get(getMillis());
163    }
164
165    /**
166     * Get the day of month field value.
167     * <p>
168     * The values for the day of month are defined in {@link org.joda.time.DateTimeConstants}.
169     * 
170     * @return the day of month
171     */
172    public int getDayOfMonth() {
173        return getChronology().dayOfMonth().get(getMillis());
174    }
175
176    /**
177     * Get the day of week field value.
178     * <p>
179     * The values for the day of week are defined in {@link org.joda.time.DateTimeConstants}.
180     * 
181     * @return the day of week
182     */
183    public int getDayOfWeek() {
184        return getChronology().dayOfWeek().get(getMillis());
185    }
186
187    //-----------------------------------------------------------------------
188    /**
189     * Get the hour of day field value.
190     *
191     * @return the hour of day
192     */
193    public int getHourOfDay() {
194        return getChronology().hourOfDay().get(getMillis());
195    }
196
197    /**
198     * Get the minute of day field value.
199     *
200     * @return the minute of day
201     */
202    public int getMinuteOfDay() {
203        return getChronology().minuteOfDay().get(getMillis());
204    }
205
206    /**
207     * Get the minute of hour field value.
208     *
209     * @return the minute of hour
210     */
211    public int getMinuteOfHour() {
212        return getChronology().minuteOfHour().get(getMillis());
213    }
214
215    /**
216     * Get the second of day field value.
217     *
218     * @return the second of day
219     */
220    public int getSecondOfDay() {
221        return getChronology().secondOfDay().get(getMillis());
222    }
223
224    /**
225     * Get the second of minute field value.
226     *
227     * @return the second of minute
228     */
229    public int getSecondOfMinute() {
230        return getChronology().secondOfMinute().get(getMillis());
231    }
232
233    /**
234     * Get the millis of day field value.
235     *
236     * @return the millis of day
237     */
238    public int getMillisOfDay() {
239        return getChronology().millisOfDay().get(getMillis());
240    }
241
242    /**
243     * Get the millis of second field value.
244     *
245     * @return the millis of second
246     */
247    public int getMillisOfSecond() {
248        return getChronology().millisOfSecond().get(getMillis());
249    }
250
251    //-----------------------------------------------------------------------
252    /**
253     * Get the date time as a <code>java.util.Calendar</code>, assigning
254     * exactly the same millisecond instant.
255     * The locale is passed in, enabling Calendar to select the correct
256     * localized subclass.
257     * <p>
258     * The JDK and Joda-Time both have time zone implementations and these
259     * differ in accuracy. Joda-Time's implementation is generally more up to
260     * date and thus more accurate - for example JDK1.3 has no historical data.
261     * The effect of this is that the field values of the <code>Calendar</code>
262     * may differ from those of this object, even though the milliseond value
263     * is the same. Most of the time this just means that the JDK field values
264     * are wrong, as our time zone information is more up to date.
265     *
266     * @param locale  the locale to get the Calendar for, or default if null
267     * @return a localized Calendar initialised with this datetime
268     */
269    public Calendar toCalendar(Locale locale) {
270        if (locale == null) {
271            locale = Locale.getDefault();
272        }
273        DateTimeZone zone = getZone();
274        Calendar cal = Calendar.getInstance(zone.toTimeZone(), locale);
275        cal.setTime(toDate());
276        return cal;
277    }
278
279    /**
280     * Get the date time as a <code>java.util.GregorianCalendar</code>,
281     * assigning exactly the same millisecond instant.
282     * <p>
283     * The JDK and Joda-Time both have time zone implementations and these
284     * differ in accuracy. Joda-Time's implementation is generally more up to
285     * date and thus more accurate - for example JDK1.3 has no historical data.
286     * The effect of this is that the field values of the <code>Calendar</code>
287     * may differ from those of this object, even though the milliseond value
288     * is the same. Most of the time this just means that the JDK field values
289     * are wrong, as our time zone information is more up to date.
290     *
291     * @return a GregorianCalendar initialised with this datetime
292     */
293    public GregorianCalendar toGregorianCalendar() {
294        DateTimeZone zone = getZone();
295        GregorianCalendar cal = new GregorianCalendar(zone.toTimeZone());
296        cal.setTime(toDate());
297        return cal;
298    }
299
300    //-----------------------------------------------------------------------
301    /**
302     * Output the instant using the specified format pattern.
303     *
304     * @param pattern  the pattern specification, null means use <code>toString</code>
305     * @see  org.joda.time.format.DateTimeFormat
306     */
307    public String toString(String pattern) {
308        if (pattern == null) {
309            return toString();
310        }
311        return DateTimeFormat.forPattern(pattern).print(this);
312    }
313
314    /**
315     * Output the instant using the specified format pattern.
316     *
317     * @param pattern  the pattern specification, null means use <code>toString</code>
318     * @param locale  Locale to use, null means default
319     * @see  org.joda.time.format.DateTimeFormat
320     */
321    public String toString(String pattern, Locale locale) throws IllegalArgumentException {
322        if (pattern == null) {
323            return toString();
324        }
325        return DateTimeFormat.forPattern(pattern).withLocale(locale).print(this);
326    }
327
328}