public Calendar parseTimestamp()

in src/main/java/org/apache/commons/net/ftp/parser/FTPTimestampParserImpl.java [261:318]


    public Calendar parseTimestamp(final String timestampStr, final Calendar serverTime) throws ParseException {
        final Calendar working = (Calendar) serverTime.clone();
        working.setTimeZone(getServerTimeZone()); // is this needed?

        Date parsed;

        if (recentDateFormat != null) {
            final Calendar now = (Calendar) serverTime.clone();// Copy this, because we may change it
            now.setTimeZone(this.getServerTimeZone());
            if (lenientFutureDates) {
                // add a day to "now" so that "slop" doesn't cause a date
                // slightly in the future to roll back a full year. (Bug 35181 => NET-83)
                now.add(Calendar.DAY_OF_MONTH, 1);
            }
            // The Java SimpleDateFormat class uses the epoch year 1970 if not present in the input
            // As 1970 was not a leap year, it cannot parse "Feb 29" correctly.
            // Java 1.5+ returns Mar 1 1970
            // Temporarily add the current year to the short date time
            // to cope with short-date leap year strings.
            // Since Feb 29 is more that 6 months from the end of the year, this should be OK for
            // all instances of short dates which are +- 6 months from current date.
            // TODO this won't always work for systems that use short dates +0/-12months
            // e.g. if today is Jan 1 2001 and the short date is Feb 29
            final String year = Integer.toString(now.get(Calendar.YEAR));
            final String timeStampStrPlusYear = timestampStr + " " + year;
            final SimpleDateFormat hackFormatter = new SimpleDateFormat(recentDateFormat.toPattern() + " yyyy", recentDateFormat.getDateFormatSymbols());
            hackFormatter.setLenient(false);
            hackFormatter.setTimeZone(recentDateFormat.getTimeZone());
            final ParsePosition pp = new ParsePosition(0);
            parsed = hackFormatter.parse(timeStampStrPlusYear, pp);
            // Check if we parsed the full string, if so it must have been a short date originally
            if (parsed != null && pp.getIndex() == timeStampStrPlusYear.length()) {
                working.setTime(parsed);
                if (working.after(now)) { // must have been last year instead
                    working.add(Calendar.YEAR, -1);
                }
                setPrecision(recentDateSmallestUnitIndex, working);
                return working;
            }
        }

        final ParsePosition pp = new ParsePosition(0);
        parsed = defaultDateFormat.parse(timestampStr, pp);
        // note, length checks are mandatory for us since
        // SimpleDateFormat methods will succeed if less than
        // full string is matched. They will also accept,
        // despite "leniency" setting, a two-digit number as
        // a valid year (e.g. 22:04 will parse as 22 A.D.)
        // so could mistakenly confuse an hour with a year,
        // if we don't insist on full length parsing.
        if ((parsed == null) || (pp.getIndex() != timestampStr.length())) {
            throw new ParseException("Timestamp '" + timestampStr + "' could not be parsed using a server time of " + serverTime.getTime().toString(),
                    pp.getErrorIndex());
        }
        working.setTime(parsed);
        setPrecision(defaultDateSmallestUnitIndex, working);
        return working;
    }