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     */
016    package org.joda.time.base;
017    
018    import java.util.Calendar;
019    import java.util.GregorianCalendar;
020    import java.util.Locale;
021    
022    import org.joda.time.DateTimeFieldType;
023    import org.joda.time.DateTimeZone;
024    import org.joda.time.ReadableDateTime;
025    import 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     */
043    public 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    }