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