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    *      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      * Formats a calendar into a specific pattern. The TimeZone from the calendar
202      * will be used for formatting.
203      *
204      * @param calendar  the calendar to format, not null
205      * @param pattern  the pattern to use to format the calendar, not null
206      * @return the formatted calendar
207      * @see FastDateFormat#format(Calendar)
208      * @since 2.4
209      */
210     public static String format(final Calendar calendar, final String pattern) {
211         return format(calendar, pattern, getTimeZone(calendar), null);
212     }
213 
214     /**
215      * Formats a calendar into a specific pattern in a locale. The TimeZone from the calendar
216      * will be used for formatting.
217      *
218      * @param calendar  the calendar to format, not null
219      * @param pattern  the pattern to use to format the calendar, not null
220      * @param locale  the locale to use, may be {@code null}
221      * @return the formatted calendar
222      * @see FastDateFormat#format(Calendar)
223      * @since 2.4
224      */
225     public static String format(final Calendar calendar, final String pattern, final Locale locale) {
226         return format(calendar, pattern, getTimeZone(calendar), locale);
227     }
228 
229     /**
230      * Formats a calendar into a specific pattern in a time zone.
231      *
232      * @param calendar  the calendar to format, not null
233      * @param pattern  the pattern to use to format the calendar, not null
234      * @param timeZone  the time zone  to use, may be {@code null}
235      * @return the formatted calendar
236      * @see FastDateFormat#format(Calendar)
237      * @since 2.4
238      */
239     public static String format(final Calendar calendar, final String pattern, final TimeZone timeZone) {
240         return format(calendar, pattern, timeZone, null);
241     }
242 
243     /**
244      * Formats a calendar into a specific pattern in a time zone and locale.
245      *
246      * @param calendar  the calendar to format, not null
247      * @param pattern  the pattern to use to format the calendar, not null
248      * @param timeZone  the time zone  to use, may be {@code null}
249      * @param locale  the locale to use, may be {@code null}
250      * @return the formatted calendar
251      * @see FastDateFormat#format(Calendar)
252      * @since 2.4
253      */
254     public static String format(final Calendar calendar, final String pattern, final TimeZone timeZone, final Locale locale) {
255         final FastDateFormat df = FastDateFormat.getInstance(pattern, timeZone, locale);
256         return df.format(calendar);
257     }
258 
259     /**
260      * Formats a date/time into a specific pattern.
261      *
262      * @param date  the date to format, not null
263      * @param pattern  the pattern to use to format the date, not null
264      * @return the formatted date
265      */
266     public static String format(final Date date, final String pattern) {
267         return format(date, pattern, null, null);
268     }
269 
270     /**
271      * Formats a date/time into a specific pattern in a locale.
272      *
273      * @param date  the date to format, not null
274      * @param pattern  the pattern to use to format the date, not null
275      * @param locale  the locale to use, may be {@code null}
276      * @return the formatted date
277      */
278     public static String format(final Date date, final String pattern, final Locale locale) {
279         return format(date, pattern, null, locale);
280     }
281 
282     /**
283      * Formats a date/time into a specific pattern in a time zone.
284      *
285      * @param date  the date to format, not null
286      * @param pattern  the pattern to use to format the date, not null
287      * @param timeZone  the time zone  to use, may be {@code null}
288      * @return the formatted date
289      */
290     public static String format(final Date date, final String pattern, final TimeZone timeZone) {
291         return format(date, pattern, timeZone, null);
292     }
293 
294     /**
295      * Formats a date/time into a specific pattern in a time zone and locale.
296      *
297      * @param date  the date to format, not null
298      * @param pattern  the pattern to use to format the date, not null, not null
299      * @param timeZone  the time zone  to use, may be {@code null}
300      * @param locale  the locale to use, may be {@code null}
301      * @return the formatted date
302      */
303     public static String format(final Date date, final String pattern, final TimeZone timeZone, final Locale locale) {
304         final FastDateFormat df = FastDateFormat.getInstance(pattern, timeZone, locale);
305         return df.format(date);
306     }
307 
308     /**
309      * Formats a date/time into a specific pattern.
310      *
311      * @param millis  the date to format expressed in milliseconds
312      * @param pattern  the pattern to use to format the date, not null
313      * @return the formatted date
314      */
315     public static String format(final long millis, final String pattern) {
316         return format(new Date(millis), pattern, null, null);
317     }
318 
319     /**
320      * Formats a date/time into a specific pattern in a locale.
321      *
322      * @param millis  the date to format expressed in milliseconds
323      * @param pattern  the pattern to use to format the date, not null
324      * @param locale  the locale to use, may be {@code null}
325      * @return the formatted date
326      */
327     public static String format(final long millis, final String pattern, final Locale locale) {
328         return format(new Date(millis), pattern, null, locale);
329     }
330 
331     /**
332      * Formats a date/time into a specific pattern in a time zone.
333      *
334      * @param millis  the time expressed in milliseconds
335      * @param pattern  the pattern to use to format the date, not null
336      * @param timeZone  the time zone  to use, may be {@code null}
337      * @return the formatted date
338      */
339     public static String format(final long millis, final String pattern, final TimeZone timeZone) {
340         return format(new Date(millis), pattern, timeZone, null);
341     }
342 
343     /**
344      * Formats a date/time into a specific pattern in a time zone and locale.
345      *
346      * @param millis  the date to format expressed in milliseconds
347      * @param pattern  the pattern to use to format the date, not null
348      * @param timeZone  the time zone  to use, may be {@code null}
349      * @param locale  the locale to use, may be {@code null}
350      * @return the formatted date
351      */
352     public static String format(final long millis, final String pattern, final TimeZone timeZone, final Locale locale) {
353         return format(new Date(millis), pattern, timeZone, locale);
354     }
355 
356     /**
357      * Formats a date/time into a specific pattern using the UTC time zone.
358      *
359      * @param date  the date to format, not null
360      * @param pattern  the pattern to use to format the date, not null
361      * @return the formatted date
362      */
363     public static String formatUTC(final Date date, final String pattern) {
364         return format(date, pattern, UTC_TIME_ZONE, null);
365     }
366 
367     /**
368      * Formats a date/time into a specific pattern using the UTC time zone.
369      *
370      * @param date  the date to format, not null
371      * @param pattern  the pattern to use to format the date, not null
372      * @param locale  the locale to use, may be {@code null}
373      * @return the formatted date
374      */
375     public static String formatUTC(final Date date, final String pattern, final Locale locale) {
376         return format(date, pattern, UTC_TIME_ZONE, locale);
377     }
378 
379     /**
380      * Formats a date/time into a specific pattern using the UTC time zone.
381      *
382      * @param millis  the date to format expressed in milliseconds
383      * @param pattern  the pattern to use to format the date, not null
384      * @return the formatted date
385      */
386     public static String formatUTC(final long millis, final String pattern) {
387         return format(new Date(millis), pattern, UTC_TIME_ZONE, null);
388     }
389 
390     /**
391      * Formats a date/time into a specific pattern using the UTC time zone.
392      *
393      * @param millis  the date to format expressed in milliseconds
394      * @param pattern  the pattern to use to format the date, not null
395      * @param locale  the locale to use, may be {@code null}
396      * @return the formatted date
397      */
398     public static String formatUTC(final long millis, final String pattern, final Locale locale) {
399         return format(new Date(millis), pattern, UTC_TIME_ZONE, locale);
400     }
401 
402     private static TimeZone getTimeZone(final Calendar calendar) {
403         return calendar == null ? null : calendar.getTimeZone();
404     }
405 
406     /**
407      * DateFormatUtils instances should NOT be constructed in standard programming.
408      *
409      * <p>This constructor is public to permit tools that require a JavaBean instance
410      * to operate.</p>
411      */
412     public DateFormatUtils() {
413     }
414 
415 }