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>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 * @deprecated TODO Make private in 4.0.
413 */
414 @Deprecated
415 public DateFormatUtils() {
416 // empty
417 }
418
419 }