public Date parseString(String dateString) throws ParseException {
        if (dateString == null || dateString.isEmpty()) {
            return null;
        }
        Matcher xep82WoMillisMatcher = xep80DateTimeWoMillisPattern.matcher(dateString);
        Matcher xep82Matcher = xep80DateTimePattern.matcher(dateString);

        if (xep82WoMillisMatcher.matches() || xep82Matcher.matches()) {
            String rfc822Date;
            // Convert the ISO 8601 time zone string to a RFC822 compatible format
            // since SimpleDateFormat supports ISO8601 only with Java7 or higher
            if (dateString.charAt(dateString.length() - 1) == 'Z') {
                rfc822Date = dateString.replace("Z", "+0000");
            } else {
                // If the time zone wasn't specified with 'Z', then it's in
                // ISO8601 format (i.e. '(+|-)HH:mm')
                // RFC822 needs a similar format just without the colon (i.e.
                // '(+|-)HHmm)'), so remove it
                int lastColon = dateString.lastIndexOf(':');
                rfc822Date = dateString.substring(0, lastColon) + dateString.substring(lastColon + 1);
            }

            if (xep82WoMillisMatcher.matches()) {
                synchronized (dateTimeFormatWoMillies) {
                    return dateTimeFormatWoMillies.parse(rfc822Date);
                }
            } else {
                // OF-898: Replace any number of millisecond-characters with at most three of them.
                rfc822Date = rfc822Date.replaceAll("(\\.[0-9]{3})[0-9]*", "$1");

                synchronized (dateTimeFormat) {
                    return dateTimeFormat.parse(rfc822Date);
                }
            }
        }
        throw new ParseException("Date String could not be parsed: \"" + dateString + "\"", 0);
    }
Tries to convert a given string to a Date object.
This method supports the format types defined by XEP-0082 and the format defined in legacy protocols
XEP-0082: CCYY-MM-DDThh:mm:ss[.sss]TZD
legacy: CCYYMMDDThh:mm:ss

This method either returns a Date instance as result or it will return null or throw a ParseException
in case the String couldn't be parsed.

@param dateString the String that should be parsed
@return the parsed date or null if the String could not be parsed
@throws ParseException if the date could not be parsed
xmppserver/src/main/java/org/jivesoftware/util/XMPPDateTimeFormat.java