All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.day.cq.dam.commons.util.DateParser Maven / Gradle / Ivy

There is a newer version: 2024.11.18751.20241128T090041Z-241100
Show newest version
/*
 * Copyright 1997-2008 Day Management AG
 * Barfuesserplatz 6, 4001 Basel, Switzerland
 * All Rights Reserved.
 *
 * This software is the confidential and proprietary information of
 * Day Management AG, ("Confidential Information"). You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with Day.
 */
package com.day.cq.dam.commons.util;


import java.text.DateFormat;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 */
public final class DateParser {
    /**
     * the default logger
     */
    private static final Logger log = LoggerFactory.getLogger(DateParser.class);


    /**
     * A date format for parsing RFC 822-style dates.
     */
    private static DateFormat[] RFC822_DATE_FORMATS;

    /**
     * Patterns for the more common W3C date/time formats.
     */
    private static DateFormat[] W3C_DATE_FORMATS;

    static {
        W3C_DATE_FORMATS = new SimpleDateFormat[]{
                new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss 'GMT'Z"),

                new SimpleDateFormat("yyyy:MM:dd HH:mm:ss"),
                new SimpleDateFormat("yyyy:MM:dd HH:mm"),
                new SimpleDateFormat("yyyy:MM:dd"),
                new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"),
                new SimpleDateFormat("yyyy-MM-dd'T'HH:mm"),
                new SimpleDateFormat("yyyy-MM-dd"),
                new SimpleDateFormat("dd.MM.yyyy HH:mm:ss"),
                new SimpleDateFormat("dd.MM.yyyy")};

        RFC822_DATE_FORMATS = new SimpleDateFormat[]{
                // RFC822 dates are US-centric
                new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss z",
                        Locale.US),
                new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss",
                        Locale.US),
                new SimpleDateFormat("EEE d MMM yyyy HH:mm:ss",
                        Locale.US)};
    }

    private static Pattern w3cTZPattern = null;


    /**
     * Try to parse a date using as many methods as possible, until one
     * works.
     *
     * @param sDate the date string
     * @return the corresponding date, or null if not parseable or if the
     *         date string is empty or null
     */
    public static Date parseDate(String sDate) {
        Date result = null;

        if ((result = parseRFC822Date(sDate)) == null) {
            result = parseW3CDate(sDate);
        }
        return result;
    }

    /**
     * Parse an RFC 822-style date string.
     *
     * @param sDate the date string
     * @return the corresponding date, or null if not parseable or if the
     *         date string is empty or null
     */
    public static Date parseRFC822Date(String sDate) {
        Date result = null;

        if ((sDate != null) && (sDate.length() > 0)) {
            // DateFormat objects are not synchronized.

            synchronized (RFC822_DATE_FORMATS) {
                result = parseDate(sDate, RFC822_DATE_FORMATS, TimeZone
                        .getDefault());
            }
        }

        return result;
    }

    /**
     * Parse a W3C date string. Not comprehensive.
     *
     * @param sDate the date string
     * @return the corresponding date, or null if not parseable or if the
     *         date string is empty or null
     */
    public static Date parseW3CDate(String sDate) {
        Date result = null;

        if ((sDate != null) && (sDate.length() > 0)) {
            TimeZone timeZone = TimeZone.getDefault();

            final int tIndex = sDate.indexOf('T');
            int tzIndex;


            // First, extract the time zone, if present.
            if ((tIndex > 0) &&
                    (((tzIndex = sDate.indexOf('Z', tIndex)) != -1)
                    || ((tzIndex = sDate.indexOf('+', tIndex)) != -1)
                    || ((tzIndex = sDate.indexOf('-', tIndex)) != -1)))
            {
                timeZone = parseW3CTimeZone(sDate.substring(tzIndex));
            }

            // Now, parse the date. NOTE: DateFormat objects are not
            // synchronized.

            synchronized (W3C_DATE_FORMATS) {
                result = parseDate(sDate, W3C_DATE_FORMATS, timeZone);
            }
        }

        return result;
    }

    // -------------< private >---------------------------------------

    /**
     * Parse a date/time using an array of DateFormat objects
     *
     * @param sDate    the date string
     * @param formats  the array of DateFormat objects to try, one by one
     * @param timeZone time zone to use
     * @return the parsed date, or null if not parseable
     */
    private static Date parseDate(String sDate, DateFormat[] formats,
                                  TimeZone timeZone) {
        Date result = null;

        for (int i = 0; i < formats.length; i++) {
            formats[i].setTimeZone(timeZone);
            try {
                formats[i].setLenient(false);
                result = formats[i].parse(sDate, new ParsePosition(0));
            } catch (NumberFormatException ex) {
                result = null;
            } catch (Exception ex) {
                log.error("Unexpected exception while parsing date \""
                        + sDate + "\" using format \""
                        + formats[i].toString() + "\"", ex);
            }

            if (result != null)
                break;
        }

        return result;
    }

    /**
     * Parse a string into a W3C time zone. Returns the default time zone
     * if the string doesn't parse.
     *
     * @param tz the alleged time zone string
     * @return a TimeZone
     */
    private static TimeZone parseW3CTimeZone(String tz) {
        TimeZone timeZone = null;

        synchronized (DateParser.class) {
            try {
                w3cTZPattern = Pattern
                        .compile("^[+-][0-9][0-9]:[0-9][0-9]$");
            } catch (PatternSyntaxException ex) {
                // Should not happen.

                assert (false);
            }
        }

        // Do we have a time zone?

        switch (tz.charAt(0)) {
            case'Z':
                timeZone = TimeZone.getTimeZone("GMT");
                break;

            case'-':
            case'+':
                // +hh:mm -hh:mm

                Matcher matcher = w3cTZPattern.matcher(tz);
                if (matcher.matches()) {
                    timeZone = TimeZone.getTimeZone("GMT" + tz);
                }
                if (timeZone == null) {
                    timeZone = TimeZone.getDefault();
                }
                break;

            default:
                // Whatever it is, it's not a time zone. Assume
                // local time zone.

                timeZone = TimeZone.getDefault();
                break;

        }

        return timeZone;
    }
}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy