001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 * 
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 * 
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.lang3.time;
018
019import java.util.Calendar;
020import java.util.Date;
021import java.util.Locale;
022import java.util.TimeZone;
023
024/**
025 * <p>Date and time formatting utilities and constants.</p>
026 *
027 * <p>Formatting is performed using the thread-safe
028 * {@link org.apache.commons.lang3.time.FastDateFormat} class.</p>
029 *
030 * <p>Note that the JDK has a bug wherein calling Calendar.get(int) will 
031 * override any previously called Calendar.clear() calls. See LANG-755.</p>
032 *
033 * @since 2.0
034 * @version $Id: DateFormatUtils.java 1612038 2014-07-20 06:46:57Z ggregory $
035 */
036public class DateFormatUtils {
037
038    /**
039     * The UTC time zone (often referred to as GMT).
040     * This is private as it is mutable.
041     */
042    private static final TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone("GMT");
043    /**
044     * ISO 8601 formatter for date-time without time zone.
045     * The format used is {@code yyyy-MM-dd'T'HH:mm:ss}.
046     */
047    public static final FastDateFormat ISO_DATETIME_FORMAT
048            = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss");
049
050    /**
051     * ISO 8601 formatter for date-time with time zone.
052     * The format used is {@code yyyy-MM-dd'T'HH:mm:ssZZ}.
053     */
054    public static final FastDateFormat ISO_DATETIME_TIME_ZONE_FORMAT
055            = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ssZZ");
056
057    /**
058     * ISO 8601 formatter for date without time zone.
059     * The format used is {@code yyyy-MM-dd}.
060     */
061    public static final FastDateFormat ISO_DATE_FORMAT
062            = FastDateFormat.getInstance("yyyy-MM-dd");
063
064    /**
065     * ISO 8601-like formatter for date with time zone.
066     * The format used is {@code yyyy-MM-ddZZ}.
067     * This pattern does not comply with the formal ISO 8601 specification
068     * as the standard does not allow a time zone  without a time.
069     */
070    public static final FastDateFormat ISO_DATE_TIME_ZONE_FORMAT
071            = FastDateFormat.getInstance("yyyy-MM-ddZZ");
072
073    /**
074     * ISO 8601 formatter for time without time zone.
075     * The format used is {@code 'T'HH:mm:ss}.
076     */
077    public static final FastDateFormat ISO_TIME_FORMAT
078            = FastDateFormat.getInstance("'T'HH:mm:ss");
079
080    /**
081     * ISO 8601 formatter for time with time zone.
082     * The format used is {@code 'T'HH:mm:ssZZ}.
083     */
084    public static final FastDateFormat ISO_TIME_TIME_ZONE_FORMAT
085            = FastDateFormat.getInstance("'T'HH:mm:ssZZ");
086
087    /**
088     * ISO 8601-like formatter for time without time zone.
089     * The format used is {@code HH:mm:ss}.
090     * This pattern does not comply with the formal ISO 8601 specification
091     * as the standard requires the 'T' prefix for times.
092     */
093    public static final FastDateFormat ISO_TIME_NO_T_FORMAT
094            = FastDateFormat.getInstance("HH:mm:ss");
095
096    /**
097     * ISO 8601-like formatter for time with time zone.
098     * The format used is {@code HH:mm:ssZZ}.
099     * This pattern does not comply with the formal ISO 8601 specification
100     * as the standard requires the 'T' prefix for times.
101     */
102    public static final FastDateFormat ISO_TIME_NO_T_TIME_ZONE_FORMAT
103            = FastDateFormat.getInstance("HH:mm:ssZZ");
104
105    /**
106     * SMTP (and probably other) date headers.
107     * The format used is {@code EEE, dd MMM yyyy HH:mm:ss Z} in US locale.
108     */
109    public static final FastDateFormat SMTP_DATETIME_FORMAT
110            = FastDateFormat.getInstance("EEE, dd MMM yyyy HH:mm:ss Z", Locale.US);
111
112    //-----------------------------------------------------------------------
113    /**
114     * <p>DateFormatUtils instances should NOT be constructed in standard programming.</p>
115     *
116     * <p>This constructor is public to permit tools that require a JavaBean instance
117     * to operate.</p>
118     */
119    public DateFormatUtils() {
120        super();
121    }
122
123    /**
124     * <p>Formats a date/time into a specific pattern using the UTC time zone.</p>
125     * 
126     * @param millis  the date to format expressed in milliseconds
127     * @param pattern  the pattern to use to format the date, not null
128     * @return the formatted date
129     */
130    public static String formatUTC(final long millis, final String pattern) {
131        return format(new Date(millis), pattern, UTC_TIME_ZONE, null);
132    }
133
134    /**
135     * <p>Formats a date/time into a specific pattern using the UTC time zone.</p>
136     * 
137     * @param date  the date to format, not null
138     * @param pattern  the pattern to use to format the date, not null
139     * @return the formatted date
140     */
141    public static String formatUTC(final Date date, final String pattern) {
142        return format(date, pattern, UTC_TIME_ZONE, null);
143    }
144    
145    /**
146     * <p>Formats a date/time into a specific pattern using the UTC time zone.</p>
147     * 
148     * @param millis  the date to format expressed in milliseconds
149     * @param pattern  the pattern to use to format the date, not null
150     * @param locale  the locale to use, may be <code>null</code>
151     * @return the formatted date
152     */
153    public static String formatUTC(final long millis, final String pattern, final Locale locale) {
154        return format(new Date(millis), pattern, UTC_TIME_ZONE, locale);
155    }
156
157    /**
158     * <p>Formats a date/time into a specific pattern using the UTC time zone.</p>
159     * 
160     * @param date  the date to format, not null
161     * @param pattern  the pattern to use to format the date, not null
162     * @param locale  the locale to use, may be <code>null</code>
163     * @return the formatted date
164     */
165    public static String formatUTC(final Date date, final String pattern, final Locale locale) {
166        return format(date, pattern, UTC_TIME_ZONE, locale);
167    }
168    
169    /**
170     * <p>Formats a date/time into a specific pattern.</p>
171     * 
172     * @param millis  the date to format expressed in milliseconds
173     * @param pattern  the pattern to use to format the date, not null
174     * @return the formatted date
175     */
176    public static String format(final long millis, final String pattern) {
177        return format(new Date(millis), pattern, null, null);
178    }
179
180    /**
181     * <p>Formats a date/time into a specific pattern.</p>
182     * 
183     * @param date  the date to format, not null
184     * @param pattern  the pattern to use to format the date, not null
185     * @return the formatted date
186     */
187    public static String format(final Date date, final String pattern) {
188        return format(date, pattern, null, null);
189    }
190
191    /**
192     * <p>Formats a calendar into a specific pattern.</p>
193     * 
194     * @param calendar  the calendar to format, not null
195     * @param pattern  the pattern to use to format the calendar, not null
196     * @return the formatted calendar
197     * @see FastDateFormat#format(Calendar)
198     * @since 2.4
199     */
200    public static String format(final Calendar calendar, final String pattern) {
201        return format(calendar, pattern, null, null);
202    }
203    
204    /**
205     * <p>Formats a date/time into a specific pattern in a time zone.</p>
206     * 
207     * @param millis  the time expressed in milliseconds
208     * @param pattern  the pattern to use to format the date, not null
209     * @param timeZone  the time zone  to use, may be <code>null</code>
210     * @return the formatted date
211     */
212    public static String format(final long millis, final String pattern, final TimeZone timeZone) {
213        return format(new Date(millis), pattern, timeZone, null);
214    }
215
216    /**
217     * <p>Formats a date/time into a specific pattern in a time zone.</p>
218     * 
219     * @param date  the date to format, not null
220     * @param pattern  the pattern to use to format the date, not null
221     * @param timeZone  the time zone  to use, may be <code>null</code>
222     * @return the formatted date
223     */
224    public static String format(final Date date, final String pattern, final TimeZone timeZone) {
225        return format(date, pattern, timeZone, null);
226    }
227
228    /**
229     * <p>Formats a calendar into a specific pattern in a time zone.</p>
230     * 
231     * @param calendar  the calendar to format, not null
232     * @param pattern  the pattern to use to format the calendar, not null
233     * @param timeZone  the time zone  to use, may be <code>null</code>
234     * @return the formatted calendar
235     * @see FastDateFormat#format(Calendar)
236     * @since 2.4
237     */
238    public static String format(final Calendar calendar, final String pattern, final TimeZone timeZone) {
239        return format(calendar, pattern, timeZone, null);
240    }
241
242    /**
243     * <p>Formats a date/time into a specific pattern in a locale.</p>
244     * 
245     * @param millis  the date to format expressed in milliseconds
246     * @param pattern  the pattern to use to format the date, not null
247     * @param locale  the locale to use, may be <code>null</code>
248     * @return the formatted date
249     */
250    public static String format(final long millis, final String pattern, final Locale locale) {
251        return format(new Date(millis), pattern, null, locale);
252    }
253
254    /**
255     * <p>Formats a date/time into a specific pattern in a locale.</p>
256     * 
257     * @param date  the date to format, not null
258     * @param pattern  the pattern to use to format the date, not null
259     * @param locale  the locale to use, may be <code>null</code>
260     * @return the formatted date
261     */
262    public static String format(final Date date, final String pattern, final Locale locale) {
263        return format(date, pattern, null, locale);
264    }
265
266    /**
267     * <p>Formats a calendar into a specific pattern in a locale.</p>
268     * 
269     * @param calendar  the calendar to format, not null
270     * @param pattern  the pattern to use to format the calendar, not null
271     * @param locale  the locale to use, may be <code>null</code>
272     * @return the formatted calendar
273     * @see FastDateFormat#format(Calendar)
274     * @since 2.4
275     */
276    public static String format(final Calendar calendar, final String pattern, final Locale locale) {
277        return format(calendar, pattern, null, locale);
278    }
279
280    /**
281     * <p>Formats a date/time into a specific pattern in a time zone  and locale.</p>
282     * 
283     * @param millis  the date to format expressed in milliseconds
284     * @param pattern  the pattern to use to format the date, not null
285     * @param timeZone  the time zone  to use, may be <code>null</code>
286     * @param locale  the locale to use, may be <code>null</code>
287     * @return the formatted date
288     */
289    public static String format(final long millis, final String pattern, final TimeZone timeZone, final Locale locale) {
290        return format(new Date(millis), pattern, timeZone, locale);
291    }
292
293    /**
294     * <p>Formats a date/time into a specific pattern in a time zone  and locale.</p>
295     * 
296     * @param date  the date to format, not null
297     * @param pattern  the pattern to use to format the date, not null, not null
298     * @param timeZone  the time zone  to use, may be <code>null</code>
299     * @param locale  the locale to use, may be <code>null</code>
300     * @return the formatted date
301     */
302    public static String format(final Date date, final String pattern, final TimeZone timeZone, final Locale locale) {
303        final FastDateFormat df = FastDateFormat.getInstance(pattern, timeZone, locale);
304        return df.format(date);
305    }
306
307    /**
308     * <p>Formats a calendar into a specific pattern in a time zone  and locale.</p>
309     * 
310     * @param calendar  the calendar to format, not null
311     * @param pattern  the pattern to use to format the calendar, not null
312     * @param timeZone  the time zone  to use, may be <code>null</code>
313     * @param locale  the locale to use, may be <code>null</code>
314     * @return the formatted calendar
315     * @see FastDateFormat#format(Calendar)
316     * @since 2.4
317     */
318    public static String format(final Calendar calendar, final String pattern, final TimeZone timeZone, final Locale locale) {
319        final FastDateFormat df = FastDateFormat.getInstance(pattern, timeZone, locale);
320        return df.format(calendar);
321    }
322
323}