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