src/main/java/org/jivesoftware/smack/util/StringUtils.java
public static Date parseDate(String dateString) throws ParseException {
        Matcher matcher = xep0091Pattern.matcher(dateString);

        /*
         * if date is in XEP-0091 format handle ambiguous dates missing the
         * leading zero in month and day
         */
        if (matcher.matches()) {
            int length = dateString.split("T")[0].length();

            if (length < 8) {
                Date date = handleDateWithMissingLeadingZeros(dateString,
                        length);

                if (date != null)
                    return date;
            } else {
                synchronized (xep0091Formatter) {
                    return xep0091Formatter.parse(dateString);
                }
            }
        } else {
            for (PatternCouplings coupling : couplings) {
                matcher = coupling.pattern.matcher(dateString);

                if (matcher.matches()) {
                    if (coupling.needToConvertTimeZone) {
                        dateString = coupling.convertTime(dateString);
                    }

                    synchronized (coupling.formatter) {
                        return coupling.formatter.parse(dateString);
                    }
                }
            }
        }

        /*
         * We assume it is the XEP-0082 DateTime profile with no milliseconds at
         * this point. If it isn't, is is just not parseable, then we attempt to
         * parse it regardless and let it throw the ParseException.
         */
        synchronized (dateTimeNoMillisFormatter) {
            return dateTimeNoMillisFormatter.parse(dateString);
        }
    }
public static Date parseDate(String dateString) throws ParseException {
        Matcher matcher = xep0091Pattern.matcher(dateString);

        /*
         * if date is in XEP-0091 format handle ambiguous dates missing the
         * leading zero in month and day
         */
        if (matcher.matches()) {
            int length = dateString.split("T")[0].length();

            if (length < 8) {
                Date date = handleDateWithMissingLeadingZeros(dateString,
                        length);

                if (date != null)
                    return date;
            } else {
                synchronized (xep0091Formatter) {
                    return xep0091Formatter.parse(dateString);
                }
            }
        } else {
            for (PatternCouplings coupling : couplings) {
                matcher = coupling.pattern.matcher(dateString);

                if (matcher.matches()) {
                    if (coupling.needToConvertTimeZone) {
                        dateString = coupling.convertTime(dateString);
                    }

                    synchronized (coupling.formatter) {
                        return coupling.formatter.parse(dateString);
                    }
                }
            }
        }

        /*
         * We assume it is the XEP-0082 DateTime profile with no milliseconds at
         * this point. If it isn't, is is just not parseable, then we attempt to
         * parse it regardless and let it throw the ParseException.
         */
        synchronized (dateTimeNoMillisFormatter) {
            return dateTimeNoMillisFormatter.parse(dateString);
        }
    }
Parses the given date string in either of the three profiles of <a
href="http://xmpp.org/extensions/xep-0082.html">XEP-0082 - XMPP Date and
Time Profiles</a> or <a
href="http://xmpp.org/extensions/xep-0091.html">XEP-0091 - Legacy Delayed
Delivery</a> format.
<p>
This method uses internal date formatters and is thus threadsafe.

@param dateString
the date string to parse
@return the parsed Date
@throws ParseException
if the specified string cannot be parsed