001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * https://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.lang3.time; 018 019import java.util.Calendar; 020import java.util.Date; 021import java.util.Locale; 022import java.util.TimeZone; 023 024/** 025 * Date and time formatting utilities and constants. 026 * 027 * <p> 028 * Formatting is performed using the thread-safe 029 * {@link org.apache.commons.lang3.time.FastDateFormat} class. 030 * </p> 031 * 032 * <p> 033 * Note that the JDK has a bug wherein calling Calendar.get(int) will 034 * override any previously called Calendar.clear() calls. See LANG-755. 035 * </p> 036 * 037 * <p> 038 * Note that when using capital YYYY instead of lowercase yyyy, the formatter 039 * will assume current year as week year is not supported. See {@link java.util.GregorianCalendar} 040 * Week Year section for an explanation on the difference between calendar and week years. 041 * </p> 042 * 043 * @since 2.0 044 */ 045public class DateFormatUtils { 046 047 /** 048 * The UTC time zone (often referred to as GMT). 049 * This is private as it is mutable. 050 */ 051 private static final TimeZone UTC_TIME_ZONE = FastTimeZone.getGmtTimeZone(); 052 053 /** 054 * ISO 8601 formatter for date-time without time zone. 055 * 056 * <p> 057 * The format used is {@code yyyy-MM-dd'T'HH:mm:ss}. This format uses the 058 * default TimeZone in effect at the time of loading DateFormatUtils class. 059 * </p> 060 * 061 * @since 3.5 062 */ 063 public static final FastDateFormat ISO_8601_EXTENDED_DATETIME_FORMAT 064 = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss"); 065 066 /** 067 * @deprecated - as of 4.0, ISO_DATETIME_FORMAT will be replaced by ISO_8601_EXTENDED_DATETIME_FORMAT. 068 */ 069 @Deprecated 070 public static final FastDateFormat ISO_DATETIME_FORMAT = ISO_8601_EXTENDED_DATETIME_FORMAT; 071 072 /** 073 * ISO 8601 formatter for date-time with time zone. 074 * 075 * <p> 076 * The format used is {@code yyyy-MM-dd'T'HH:mm:ssZZ}. This format uses the 077 * default TimeZone in effect at the time of loading DateFormatUtils class. 078 * </p> 079 * 080 * @since 3.5 081 */ 082 public static final FastDateFormat ISO_8601_EXTENDED_DATETIME_TIME_ZONE_FORMAT 083 = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ssZZ"); 084 085 /** 086 * @deprecated - as of 4.0, ISO_DATETIME_TIME_ZONE_FORMAT will be replaced by ISO_8601_EXTENDED_DATETIME_TIME_ZONE_FORMAT. 087 */ 088 @Deprecated 089 public static final FastDateFormat ISO_DATETIME_TIME_ZONE_FORMAT = ISO_8601_EXTENDED_DATETIME_TIME_ZONE_FORMAT; 090 091 /** 092 * ISO 8601 formatter for date without time zone. 093 * 094 * <p> 095 * The format used is {@code yyyy-MM-dd}. This format uses the 096 * default TimeZone in effect at the time of loading DateFormatUtils class. 097 * </p> 098 * 099 * @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}