Index: FTPTimestampParserImpl.java =================================================================== --- FTPTimestampParserImpl.java (revision 473) +++ FTPTimestampParserImpl.java (working copy) @@ -41,6 +41,7 @@ private SimpleDateFormat defaultDateFormat; private SimpleDateFormat recentDateFormat; + private SimpleDateFormat recentWithYearDateFormat; /** @@ -75,35 +76,62 @@ ParsePosition pp = new ParsePosition(0); Date parsed = null; - if (this.recentDateFormat != null) { - parsed = recentDateFormat.parse(timestampStr, pp); - } - if (parsed != null && pp.getIndex() == timestampStr.length()) - { - working.setTime(parsed); - working.set(Calendar.YEAR, now.get(Calendar.YEAR)); - if (working.after(now)) { - working.add(Calendar.YEAR, -1); - } - } else { + if (recentWithYearDateFormat != null) { + //For the 29. Feb of a leap year we have to parse with the correct year because + //parsing without a year defaults to 1970 which is not a leap year, then the parsing fails or we get the 1 of mrach + String timestamWithYearStr = timestampStr.trim() + " " + now.get(Calendar.YEAR); 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()) { + parsed = recentWithYearDateFormat.parse(timestamWithYearStr, pp); + if (parsed != null && pp.getIndex() == timestamWithYearStr.length()) { working.setTime(parsed); + working.set(Calendar.YEAR, now.get(Calendar.YEAR)); + if (working.after(now)) { + working.add(Calendar.YEAR, -1); + } + + return working; } else { - throw new ParseException( - "Timestamp could not be parsed with older or recent DateFormat", - pp.getIndex()); + timestamWithYearStr = timestampStr.trim() + " " + (now.get(Calendar.YEAR) - 1); + pp = new ParsePosition(0); + parsed = recentWithYearDateFormat.parse(timestamWithYearStr, pp); + if (parsed != null && pp.getIndex() == timestamWithYearStr.length()) { + working.setTime(parsed); + return working; + } } + } else if (this.recentDateFormat != null) { + parsed = recentDateFormat.parse(timestampStr, pp); + if (parsed != null && pp.getIndex() == timestampStr.length()) + { + working.setTime(parsed); + working.set(Calendar.YEAR, now.get(Calendar.YEAR)); + if (working.after(now)) { + working.add(Calendar.YEAR, -1); + } + + return working; + } } - return working; + + 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()) { + working.setTime(parsed); + + return working; + } + + + throw new ParseException( + "Timestamp could not be parsed with older or recent DateFormat", + pp.getIndex()); } /** @@ -146,6 +174,11 @@ if (format != null) { this.recentDateFormat = new SimpleDateFormat(format); this.recentDateFormat.setLenient(false); + + if (format.indexOf("y") == -1) { + this.recentWithYearDateFormat = new SimpleDateFormat(format.trim() + " yyyy"); + this.recentWithYearDateFormat.setLenient(false); + } } } @@ -179,6 +212,9 @@ if (this.recentDateFormat != null) { this.recentDateFormat.setTimeZone(serverTimeZone); } + if (this.recentWithYearDateFormat != null) { + this.recentWithYearDateFormat.setTimeZone(serverTimeZone); + } } /** @@ -223,6 +259,11 @@ } else { this.recentDateFormat = new SimpleDateFormat(recentFormatString, dfs); this.recentDateFormat.setLenient(false); + + if (recentFormatString.indexOf("y") == -1) { + this.recentWithYearDateFormat = new SimpleDateFormat(recentFormatString.trim() + " yyyy", dfs); + this.recentWithYearDateFormat.setLenient(false); + } } String defaultFormatString = config.getDefaultDateFormatStr();