Author: rwinston
Date: Sun Mar  2 12:29:07 2008
New Revision: 632831

URL: http://svn.apache.org/viewvc?rev=632831&view=rev
Log:
NET-188

Modified:
    
commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/parser/FTPTimestampParserImpl.java

Modified: 
commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/parser/FTPTimestampParserImpl.java
URL: 
http://svn.apache.org/viewvc/commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/parser/FTPTimestampParserImpl.java?rev=632831&r1=632830&r2=632831&view=diff
==============================================================================
--- 
commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/parser/FTPTimestampParserImpl.java
 (original)
+++ 
commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/parser/FTPTimestampParserImpl.java
 Sun Mar  2 12:29:07 2008
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.ftp.parser;
 
 import java.text.DateFormatSymbols;
@@ -22,6 +23,7 @@
 import java.text.SimpleDateFormat;
 import java.util.Calendar;
 import java.util.Date;
+import java.util.GregorianCalendar;
 import java.util.TimeZone;
 
 import org.apache.commons.net.ftp.Configurable;
@@ -71,44 +73,65 @@
        public Calendar parseTimestamp(String timestampStr) throws 
ParseException {
                Calendar now = Calendar.getInstance();
                now.setTimeZone(this.getServerTimeZone());
-               
+
                Calendar working = Calendar.getInstance();
-               working.setTimeZone(this.getServerTimeZone());
+               working.setTimeZone(getServerTimeZone());
                ParsePosition pp = new ParsePosition(0);
 
                Date parsed = null;
-               if (this.recentDateFormat != null) {
+               if (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 (this.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)
-                           now.add(Calendar.DATE, 1);
+
+                       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)
+                               now.add(Calendar.DATE, 1);
                        }    
                        if (working.after(now)) {
                                working.add(Calendar.YEAR, -1);
                        }
                } else {
-                       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()) {
+                       // Temporarily add the current year to the short date 
time
+                       // to cope with short-date leap year strings.
+                       // e.g. Java's DateFormatter will assume that "Feb 29 
12:00" refers to 
+                       // Feb 29 1970 (an invalid date) rather than a 
potentially valid leap year date.
+                       // This is pretty bad hack to work around the 
deficiencies of the JDK date/time classes.
+                       if (recentDateFormat != null && 
+                                       new 
GregorianCalendar().isLeapYear(now.get(Calendar.YEAR))) {
+                               pp = new ParsePosition(0);
+                               int year = 
Calendar.getInstance().get(Calendar.YEAR);
+                               String timeStampStrPlusYear = timestampStr + " 
" + year;
+                               SimpleDateFormat hackFormatter = new 
SimpleDateFormat(recentDateFormat.toPattern() + " yyyy", 
+                                               
recentDateFormat.getDateFormatSymbols());
+                               hackFormatter.setLenient(false);
+                               
hackFormatter.setTimeZone(recentDateFormat.getTimeZone());
+                               parsed = 
hackFormatter.parse(timeStampStrPlusYear, pp);
+                       }
+                       if (parsed != null && pp.getIndex() == 
timestampStr.length() + 5) {
                                working.setTime(parsed);
-                       } else {
-                               throw new ParseException(
-                                       "Timestamp could not be parsed with 
older or recent DateFormat", 
-                                       pp.getIndex());
+                       }
+                       else {
+                               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);
+                               } else {
+                                       throw new ParseException(
+                                                       "Timestamp could not be 
parsed with older or recent DateFormat", 
+                                                       pp.getIndex());
+                               }
                        }
                }
                return working;
@@ -257,3 +280,4 @@
         this.lenientFutureDates = lenientFutureDates;
     }
 }
+


Reply via email to