001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one
003 *  or more contributor license agreements.  See the NOTICE file
004 *  distributed with this work for additional information
005 *  regarding copyright ownership.  The ASF licenses this file
006 *  to you under the Apache License, Version 2.0 (the
007 *  "License"); you may not use this file except in compliance
008 *  with the License.  You may obtain a copy of the License at
009 *  
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *  
012 *  Unless required by applicable law or agreed to in writing,
013 *  software distributed under the License is distributed on an
014 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *  KIND, either express or implied.  See the License for the
016 *  specific language governing permissions and limitations
017 *  under the License. 
018 *  
019 */
020package org.apache.mina.http;
021
022import java.text.DateFormat;
023import java.text.ParseException;
024import java.text.SimpleDateFormat;
025import java.util.Calendar;
026import java.util.Date;
027import java.util.Locale;
028import java.util.TimeZone;
029import java.util.regex.Pattern;
030
031public class DateUtil {
032
033    private final static Locale LOCALE = Locale.US;
034    private final static TimeZone GMT_ZONE;
035    private final static String RFC_1123_PATTERN = "EEE, dd MMM yyyy HH:mm:ss zzz";
036    private final static DateFormat RFC_1123_FORMAT;
037
038    /** Pattern to find digits only. */
039    private final static Pattern DIGIT_PATTERN = Pattern.compile("^\\d+$");
040
041    static {
042        RFC_1123_FORMAT = new SimpleDateFormat(DateUtil.RFC_1123_PATTERN, DateUtil.LOCALE);
043        GMT_ZONE = TimeZone.getTimeZone("GMT");
044        DateUtil.RFC_1123_FORMAT.setTimeZone(DateUtil.GMT_ZONE);
045    }
046
047    public static String getCurrentAsString() {
048        synchronized(DateUtil.RFC_1123_FORMAT) {
049            return DateUtil.RFC_1123_FORMAT.format(new Date()); //NOPMD
050        }
051    }
052
053    /**
054     * Translate a given date <code>String</code> in the <em>RFC 1123</em>
055     * format to a <code>long</code> representing the number of milliseconds
056     * since epoch.
057     * 
058     * @param dateString a date <code>String</code> in the <em>RFC 1123</em>
059     *            format.
060     * @return the parsed <code>Date</code> in milliseconds.
061     */
062    private static long parseDateStringToMilliseconds(final String dateString) {
063
064        try {
065            synchronized (DateUtil.RFC_1123_FORMAT) {
066                return DateUtil.RFC_1123_FORMAT.parse(dateString).getTime(); //NOPMD
067            }
068        } catch (final ParseException e) {
069            return 0;
070        }
071    }
072
073    /**
074     * Parse a given date <code>String</code> to a <code>long</code>
075     * representation of the time. Where the provided value is all digits the
076     * value is returned as a <code>long</code>, otherwise attempt is made to
077     * parse the <code>String</code> as a <em>RFC 1123</em> date.
078     * 
079     * @param dateValue the value to parse.
080     * @return the <code>long</code> value following parse, or zero where not
081     *         successful.
082     */
083    public static long parseToMilliseconds(final String dateValue) {
084
085        long ms = 0;
086
087        if (DateUtil.DIGIT_PATTERN.matcher(dateValue).matches()) {
088            ms = Long.parseLong(dateValue);
089        } else {
090            ms = parseDateStringToMilliseconds(dateValue);
091        }
092
093        return ms;
094    }
095
096    /**
097     * Converts a millisecond representation of a date to a
098     * <code>RFC 1123</code> formatted <code>String</code>.
099     * 
100     * @param dateValue the <code>Date</code> represented as milliseconds.
101     * @return a <code>String</code> representation of the date.
102     */
103    public static String parseToRFC1123(final long dateValue) {
104
105        final Calendar calendar = Calendar.getInstance();
106        calendar.setTimeInMillis(dateValue);
107
108        synchronized (DateUtil.RFC_1123_FORMAT) {
109            return DateUtil.RFC_1123_FORMAT.format(calendar.getTime()); //NOPMD
110        }
111    }
112
113    /**
114     * Convert a given <code>Date</code> object to a <code>RFC 1123</code>
115     * formatted <code>String</code>.
116     * 
117     * @param date the <code>Date</code> object to convert
118     * @return a <code>String</code> representation of the date.
119     */
120    public static String getDateAsString(Date date) {
121        synchronized (DateUtil.RFC_1123_FORMAT) {
122            return RFC_1123_FORMAT.format(date); //NOPMD
123        }
124    }
125
126}