• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 package org.apache.commons.lang3.time;
18 
19 import java.util.Calendar;
20 import java.util.Date;
21 import java.util.Locale;
22 import java.util.TimeZone;
23 
24 /**
25  * Date and time formatting utilities and constants.
26  *
27  * <p>Formatting is performed using the thread-safe
28  * {@link org.apache.commons.lang3.time.FastDateFormat} class.</p>
29  *
30  * <p>Note that the JDK has a bug wherein calling Calendar.get(int) will
31  * override any previously called Calendar.clear() calls. See LANG-755.</p>
32  *
33  * <p>Note that when using capital YYYY instead of lowercase yyyy, the formatter
34  * will assume current year as week year is not supported. See {@link java.util.GregorianCalendar}
35  * Week Year section for an explanation on the difference between calendar and week years.</p>
36  *
37  * @since 2.0
38  */
39 public class DateFormatUtils {
40 
41     /**
42      * The UTC time zone (often referred to as GMT).
43      * This is private as it is mutable.
44      */
45     private static final TimeZone UTC_TIME_ZONE = FastTimeZone.getGmtTimeZone();
46 
47     /**
48      * ISO 8601 formatter for date-time without time zone.
49      *
50      * <p>
51      * The format used is {@code yyyy-MM-dd'T'HH:mm:ss}. This format uses the
52      * default TimeZone in effect at the time of loading DateFormatUtils class.
53      * </p>
54      *
55      * @since 3.5
56      */
57     public static final FastDateFormat ISO_8601_EXTENDED_DATETIME_FORMAT
58             = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss");
59 
60     /**
61      * @deprecated - as of 4.0, ISO_DATETIME_FORMAT will be replaced by ISO_8601_EXTENDED_DATETIME_FORMAT.
62      */
63     @Deprecated
64     public static final FastDateFormat ISO_DATETIME_FORMAT = ISO_8601_EXTENDED_DATETIME_FORMAT;
65 
66     /**
67      * ISO 8601 formatter for date-time with time zone.
68      *
69      * <p>
70      * The format used is {@code yyyy-MM-dd'T'HH:mm:ssZZ}. This format uses the
71      * default TimeZone in effect at the time of loading DateFormatUtils class.
72      * </p>
73      *
74      * @since 3.5
75      */
76     public static final FastDateFormat ISO_8601_EXTENDED_DATETIME_TIME_ZONE_FORMAT
77             = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ssZZ");
78 
79     /**
80      * @deprecated - as of 4.0, ISO_DATETIME_TIME_ZONE_FORMAT will be replaced by ISO_8601_EXTENDED_DATETIME_TIME_ZONE_FORMAT.
81      */
82     @Deprecated
83     public static final FastDateFormat ISO_DATETIME_TIME_ZONE_FORMAT = ISO_8601_EXTENDED_DATETIME_TIME_ZONE_FORMAT;
84 
85     /**
86      * ISO 8601 formatter for date without time zone.
87      *
88      * <p>
89      * The format used is {@code yyyy-MM-dd}. This format uses the
90      * default TimeZone in effect at the time of loading DateFormatUtils class.
91      * </p>
92      *
93      * @since 3.5
94      */
95     public static final FastDateFormat ISO_8601_EXTENDED_DATE_FORMAT
96             = FastDateFormat.getInstance("yyyy-MM-dd");
97 
98     /**
99      * @deprecated - as of 4.0, ISO_DATE_FORMAT will be replaced by ISO_8601_EXTENDED_DATE_FORMAT.
100      */
101     @Deprecated
102     public static final FastDateFormat ISO_DATE_FORMAT = ISO_8601_EXTENDED_DATE_FORMAT;
103 
104     /**
105      * ISO 8601-like formatter for date with time zone.
106      *
107      * <p>
108      * The format used is {@code yyyy-MM-ddZZ}. This pattern does not comply
109      * with the formal ISO 8601 specification as the standard does not allow
110      * a time zone  without a time. This format uses the default TimeZone in
111      * effect at the time of loading DateFormatUtils class.
112      * </p>
113      *
114      * @deprecated - as of 4.0, ISO_DATE_TIME_ZONE_FORMAT will be removed.
115      */
116     @Deprecated
117     public static final FastDateFormat ISO_DATE_TIME_ZONE_FORMAT
118             = FastDateFormat.getInstance("yyyy-MM-ddZZ");
119 
120     /**
121      * Non-compliant formatter for time without time zone (ISO 8601 does not
122      * prefix 'T' for standalone time value).
123      *
124      * <p>
125      * The format used is {@code 'T'HH:mm:ss}. This format uses the default
126      * TimeZone in effect at the time of loading DateFormatUtils class.
127      * </p>
128      *
129      * @deprecated - as of 4.0, ISO_TIME_FORMAT will be removed.
130      */
131     @Deprecated
132     public static final FastDateFormat ISO_TIME_FORMAT
133             = FastDateFormat.getInstance("'T'HH:mm:ss");
134 
135     /**
136      * Non-compliant formatter for time with time zone (ISO 8601 does not
137      * prefix 'T' for standalone time value).
138      *
139      * <p>
140      * The format used is {@code 'T'HH:mm:ssZZ}. This format uses the default
141      * TimeZone in effect at the time of loading DateFormatUtils class.
142      * </p>
143      *
144      * @deprecated - as of 4.0, ISO_TIME_TIME_ZONE_FORMAT will be removed.
145      */
146     @Deprecated
147     public static final FastDateFormat ISO_TIME_TIME_ZONE_FORMAT
148             = FastDateFormat.getInstance("'T'HH:mm:ssZZ");
149 
150     /**
151      * ISO 8601 formatter for time without time zone.
152      *
153      * <p>
154      * The format used is {@code HH:mm:ss}. This format uses the default
155      * TimeZone in effect at the time of loading DateFormatUtils class.
156      * </p>
157      *
158      * @since 3.5
159      */
160     public static final FastDateFormat ISO_8601_EXTENDED_TIME_FORMAT
161             = FastDateFormat.getInstance("HH:mm:ss");
162 
163     /**
164      * @deprecated - as of 4.0, ISO_TIME_NO_T_FORMAT will be replaced by ISO_8601_EXTENDED_TIME_FORMAT.
165      */
166     @Deprecated
167     public static final FastDateFormat ISO_TIME_NO_T_FORMAT = ISO_8601_EXTENDED_TIME_FORMAT;
168 
169     /**
170      * ISO 8601 formatter for time with time zone.
171      *
172      * <p>
173      * The format used is {@code HH:mm:ssZZ}. This format uses the default
174      * TimeZone in effect at the time of loading DateFormatUtils class.
175      * </p>
176      *
177      * @since 3.5
178      */
179     public static final FastDateFormat ISO_8601_EXTENDED_TIME_TIME_ZONE_FORMAT
180             = FastDateFormat.getInstance("HH:mm:ssZZ");
181 
182     /**
183      * @deprecated - as of 4.0, ISO_TIME_NO_T_TIME_ZONE_FORMAT will be replaced by ISO_8601_EXTENDED_TIME_TIME_ZONE_FORMAT.
184      */
185     @Deprecated
186     public static final FastDateFormat ISO_TIME_NO_T_TIME_ZONE_FORMAT = ISO_8601_EXTENDED_TIME_TIME_ZONE_FORMAT;
187 
188     /**
189      * SMTP (and probably other) date headers.
190      *
191      * <p>
192      * The format used is {@code EEE, dd MMM yyyy HH:mm:ss Z} in US locale.
193      * This format uses the default TimeZone in effect at the time of loading
194      * DateFormatUtils class.
195      * </p>
196      */
197     public static final FastDateFormat SMTP_DATETIME_FORMAT
198             = FastDateFormat.getInstance("EEE, dd MMM yyyy HH:mm:ss Z", Locale.US);
199 
200     /**
201      * DateFormatUtils instances should NOT be constructed in standard programming.
202      *
203      * <p>This constructor is public to permit tools that require a JavaBean instance
204      * to operate.</p>
205      */
DateFormatUtils()206     public DateFormatUtils() {
207     }
208 
209     /**
210      * Formats a calendar into a specific pattern. The TimeZone from the calendar
211      * will be used for formatting.
212      *
213      * @param calendar  the calendar to format, not null
214      * @param pattern  the pattern to use to format the calendar, not null
215      * @return the formatted calendar
216      * @see FastDateFormat#format(Calendar)
217      * @since 2.4
218      */
format(final Calendar calendar, final String pattern)219     public static String format(final Calendar calendar, final String pattern) {
220         return format(calendar, pattern, getTimeZone(calendar), null);
221     }
222 
223     /**
224      * Formats a calendar into a specific pattern in a locale. The TimeZone from the calendar
225      * will be used for formatting.
226      *
227      * @param calendar  the calendar to format, not null
228      * @param pattern  the pattern to use to format the calendar, not null
229      * @param locale  the locale to use, may be {@code null}
230      * @return the formatted calendar
231      * @see FastDateFormat#format(Calendar)
232      * @since 2.4
233      */
format(final Calendar calendar, final String pattern, final Locale locale)234     public static String format(final Calendar calendar, final String pattern, final Locale locale) {
235         return format(calendar, pattern, getTimeZone(calendar), locale);
236     }
237 
238     /**
239      * Formats a calendar into a specific pattern in a time zone.
240      *
241      * @param calendar  the calendar to format, not null
242      * @param pattern  the pattern to use to format the calendar, not null
243      * @param timeZone  the time zone  to use, may be {@code null}
244      * @return the formatted calendar
245      * @see FastDateFormat#format(Calendar)
246      * @since 2.4
247      */
format(final Calendar calendar, final String pattern, final TimeZone timeZone)248     public static String format(final Calendar calendar, final String pattern, final TimeZone timeZone) {
249         return format(calendar, pattern, timeZone, null);
250     }
251 
252     /**
253      * Formats a calendar into a specific pattern in a time zone and locale.
254      *
255      * @param calendar  the calendar to format, not null
256      * @param pattern  the pattern to use to format the calendar, not null
257      * @param timeZone  the time zone  to use, may be {@code null}
258      * @param locale  the locale to use, may be {@code null}
259      * @return the formatted calendar
260      * @see FastDateFormat#format(Calendar)
261      * @since 2.4
262      */
format(final Calendar calendar, final String pattern, final TimeZone timeZone, final Locale locale)263     public static String format(final Calendar calendar, final String pattern, final TimeZone timeZone, final Locale locale) {
264         final FastDateFormat df = FastDateFormat.getInstance(pattern, timeZone, locale);
265         return df.format(calendar);
266     }
267 
268     /**
269      * Formats a date/time into a specific pattern.
270      *
271      * @param date  the date to format, not null
272      * @param pattern  the pattern to use to format the date, not null
273      * @return the formatted date
274      */
format(final Date date, final String pattern)275     public static String format(final Date date, final String pattern) {
276         return format(date, pattern, null, null);
277     }
278 
279     /**
280      * Formats a date/time into a specific pattern in a locale.
281      *
282      * @param date  the date to format, not null
283      * @param pattern  the pattern to use to format the date, not null
284      * @param locale  the locale to use, may be {@code null}
285      * @return the formatted date
286      */
format(final Date date, final String pattern, final Locale locale)287     public static String format(final Date date, final String pattern, final Locale locale) {
288         return format(date, pattern, null, locale);
289     }
290 
291     /**
292      * Formats a date/time into a specific pattern in a time zone.
293      *
294      * @param date  the date to format, not null
295      * @param pattern  the pattern to use to format the date, not null
296      * @param timeZone  the time zone  to use, may be {@code null}
297      * @return the formatted date
298      */
format(final Date date, final String pattern, final TimeZone timeZone)299     public static String format(final Date date, final String pattern, final TimeZone timeZone) {
300         return format(date, pattern, timeZone, null);
301     }
302 
303     /**
304      * Formats a date/time into a specific pattern in a time zone and locale.
305      *
306      * @param date  the date to format, not null
307      * @param pattern  the pattern to use to format the date, not null, not null
308      * @param timeZone  the time zone  to use, may be {@code null}
309      * @param locale  the locale to use, may be {@code null}
310      * @return the formatted date
311      */
format(final Date date, final String pattern, final TimeZone timeZone, final Locale locale)312     public static String format(final Date date, final String pattern, final TimeZone timeZone, final Locale locale) {
313         final FastDateFormat df = FastDateFormat.getInstance(pattern, timeZone, locale);
314         return df.format(date);
315     }
316 
317     /**
318      * Formats a date/time into a specific pattern.
319      *
320      * @param millis  the date to format expressed in milliseconds
321      * @param pattern  the pattern to use to format the date, not null
322      * @return the formatted date
323      */
format(final long millis, final String pattern)324     public static String format(final long millis, final String pattern) {
325         return format(new Date(millis), pattern, null, null);
326     }
327 
328     /**
329      * Formats a date/time into a specific pattern in a locale.
330      *
331      * @param millis  the date to format expressed in milliseconds
332      * @param pattern  the pattern to use to format the date, not null
333      * @param locale  the locale to use, may be {@code null}
334      * @return the formatted date
335      */
format(final long millis, final String pattern, final Locale locale)336     public static String format(final long millis, final String pattern, final Locale locale) {
337         return format(new Date(millis), pattern, null, locale);
338     }
339 
340     /**
341      * Formats a date/time into a specific pattern in a time zone.
342      *
343      * @param millis  the time expressed in milliseconds
344      * @param pattern  the pattern to use to format the date, not null
345      * @param timeZone  the time zone  to use, may be {@code null}
346      * @return the formatted date
347      */
format(final long millis, final String pattern, final TimeZone timeZone)348     public static String format(final long millis, final String pattern, final TimeZone timeZone) {
349         return format(new Date(millis), pattern, timeZone, null);
350     }
351 
352     /**
353      * Formats a date/time into a specific pattern in a time zone and locale.
354      *
355      * @param millis  the date to format expressed in milliseconds
356      * @param pattern  the pattern to use to format the date, not null
357      * @param timeZone  the time zone  to use, may be {@code null}
358      * @param locale  the locale to use, may be {@code null}
359      * @return the formatted date
360      */
format(final long millis, final String pattern, final TimeZone timeZone, final Locale locale)361     public static String format(final long millis, final String pattern, final TimeZone timeZone, final Locale locale) {
362         return format(new Date(millis), pattern, timeZone, locale);
363     }
364 
365     /**
366      * Formats a date/time into a specific pattern using the UTC time zone.
367      *
368      * @param date  the date to format, not null
369      * @param pattern  the pattern to use to format the date, not null
370      * @return the formatted date
371      */
formatUTC(final Date date, final String pattern)372     public static String formatUTC(final Date date, final String pattern) {
373         return format(date, pattern, UTC_TIME_ZONE, null);
374     }
375 
376     /**
377      * Formats a date/time into a specific pattern using the UTC time zone.
378      *
379      * @param date  the date to format, not null
380      * @param pattern  the pattern to use to format the date, not null
381      * @param locale  the locale to use, may be {@code null}
382      * @return the formatted date
383      */
formatUTC(final Date date, final String pattern, final Locale locale)384     public static String formatUTC(final Date date, final String pattern, final Locale locale) {
385         return format(date, pattern, UTC_TIME_ZONE, locale);
386     }
387 
388     /**
389      * Formats a date/time into a specific pattern using the UTC time zone.
390      *
391      * @param millis  the date to format expressed in milliseconds
392      * @param pattern  the pattern to use to format the date, not null
393      * @return the formatted date
394      */
formatUTC(final long millis, final String pattern)395     public static String formatUTC(final long millis, final String pattern) {
396         return format(new Date(millis), pattern, UTC_TIME_ZONE, null);
397     }
398 
399     /**
400      * Formats a date/time into a specific pattern using the UTC time zone.
401      *
402      * @param millis  the date to format expressed in milliseconds
403      * @param pattern  the pattern to use to format the date, not null
404      * @param locale  the locale to use, may be {@code null}
405      * @return the formatted date
406      */
formatUTC(final long millis, final String pattern, final Locale locale)407     public static String formatUTC(final long millis, final String pattern, final Locale locale) {
408         return format(new Date(millis), pattern, UTC_TIME_ZONE, locale);
409     }
410 
getTimeZone(final Calendar calendar)411     private static TimeZone getTimeZone(final Calendar calendar) {
412         return calendar == null ? null : calendar.getTimeZone();
413     }
414 
415 }
416