Mega Code Archive

 
Categories / Java Tutorial / Network
 

Parsing and formatting HTTP dates as used in cookies and other headers

import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Calendar; import java.util.Collection; import java.util.Date; import java.util.Locale; import java.util.TimeZone; /**  * A utility class for parsing and formatting HTTP dates as used in cookies and  * other headers.  This class handles dates as defined by RFC 2616 section  * 3.3.1 as well as some other common non-standard formats.  *  * @author Christopher Brown  * @author Michael Becke  */ public final class DateUtil {     /**      * Date format pattern used to parse HTTP date headers in RFC 1123 format.      */     public static final String PATTERN_RFC1123 = "EEE, dd MMM yyyy HH:mm:ss zzz";     /**      * Date format pattern used to parse HTTP date headers in RFC 1036 format.      */     public static final String PATTERN_RFC1036 = "EEEE, dd-MMM-yy HH:mm:ss zzz";     /**      * Date format pattern used to parse HTTP date headers in ANSI C      * <code>asctime()</code> format.      */     public static final String PATTERN_ASCTIME = "EEE MMM d HH:mm:ss yyyy";     private static final Collection<String> DEFAULT_PATTERNS = Arrays.asList(         new String[] {PATTERN_ASCTIME, PATTERN_RFC1036, PATTERN_RFC1123});     private static final Date DEFAULT_TWO_DIGIT_YEAR_START;     static {         Calendar calendar = Calendar.getInstance();         calendar.set(2000, Calendar.JANUARY, 1, 0, 0);         DEFAULT_TWO_DIGIT_YEAR_START = calendar.getTime();     }     private static final TimeZone GMT = TimeZone.getTimeZone("GMT");     /**      * This class should not be instantiated.      */     private DateUtil() {     }     /**      * Parses a date value.  The formats used for parsing the date value are retrieved from      * the default http params.      *      * @param dateValue the date value to parse      * @return the parsed date      * @throws DateParseException if the value could not be parsed using any of the      *                            supported date formats      */     public static Date parseDate(String dateValue) {         return parseDate(dateValue, null, null);     }     /**      * Parses the date value using the given date formats.      *      * @param dateValue   the date value to parse      * @param dateFormats the date formats to use      * @return the parsed date      * @throws DateParseException if none of the dataFormats could parse the dateValue      */     public static Date parseDate(String dateValue, Collection<String> dateFormats)         {         return parseDate(dateValue, dateFormats, null);     }     /**      * Parses the date value using the given date formats.      *      * @param dateValue   the date value to parse      * @param dateFormats the date formats to use      * @param startDate   During parsing, two digit years will be placed in the range      *                    <code>startDate</code> to <code>startDate + 100 years</code>. This value may      *                    be <code>null</code>. When <code>null</code> is given as a parameter, year      *                    <code>2000</code> will be used.      * @return the parsed date      * @throws DateParseException if none of the dataFormats could parse the dateValue      */     public static Date parseDate(         String dateValue,         Collection<String> dateFormats,         Date startDate     )  {         if (dateValue == null) {             throw new IllegalArgumentException("dateValue is null");         }         if (dateFormats == null) {             dateFormats = DEFAULT_PATTERNS;         }         if (startDate == null) {             startDate = DEFAULT_TWO_DIGIT_YEAR_START;         }         // trim single quotes around date if present         // see issue #5279         if (dateValue.length() > 1             && dateValue.startsWith("'")             && dateValue.endsWith("'")             ) {             dateValue = dateValue.substring(1, dateValue.length() - 1);         }         SimpleDateFormat dateParser = null;         for (String format : dateFormats) {             if (dateParser == null) {                 dateParser = new SimpleDateFormat(format, Locale.US);                 dateParser.setTimeZone(TimeZone.getTimeZone("GMT"));                 dateParser.set2DigitYearStart(startDate);             } else {                 dateParser.applyPattern(format);             }             try {                 return dateParser.parse(dateValue);             } catch (ParseException pe) {                 // ignore this exception, we will try the next format             }         }         // we were unable to parse the date         throw new RuntimeException("Unable to parse the date " + dateValue);     }     /**      * Formats the given date according to the RFC 1123 pattern.      *      * @param date The date to format.      * @return An RFC 1123 formatted date string.      * @see #PATTERN_RFC1123      */     public static String formatDate(Date date) {         return formatDate(date, PATTERN_RFC1123);     }     /**      * Formats the given date according to the specified pattern.  The pattern      * must conform to that used by the {@link SimpleDateFormat simple date      * format} class.      *      * @param date    The date to format.      * @param pattern The pattern to use for formatting the date.      * @return A formatted date string.      * @throws IllegalArgumentException If the given date pattern is invalid.      * @see SimpleDateFormat      */     public static String formatDate(Date date, String pattern) {         if (date == null) {             throw new IllegalArgumentException("date is null");         }         if (pattern == null) {             throw new IllegalArgumentException("pattern is null");         }         SimpleDateFormat formatter = new SimpleDateFormat(pattern, Locale.US);         formatter.setTimeZone(GMT);         return formatter.format(date);     } }