7 Replies Latest reply: Mar 4, 2008 10:32 PM by 800645 RSS

    SimpleDateFormat.parse() generate error

    807591
      I am using FC 4 and jdk-1.5.06

      Recently, I use FTPClient.listFile() provided in common-net-1.4.1 to list the file/directory in FTP server. When the timestamp of the file/directory falls into "Feb 29 00:00" to "Feb 29 23:59", FTPFile object in the returned list is "null". And, I found that SimpleDateFormat.parse() returned "null" when passing this timestamp into this function so that FTPFile object become "null" also.

      Then, I wrote a simple program to test this SimpleDateFormat.parse(). The following is my simple program
      SimpleDateFormat clSdf=new SimpleDateFormat("MMM d HH:mm");
      clSdf.setLenient(false);
      ParsePosition clPos=new ParsePosition(0);
      Date clDate=clSdf.parse("Feb 29 00:00", clPos);
      The clDate object is "null".
      If I didn't call "clSdf.setLenient(false);", clDate.toString() returns "Mar 1 00:00:00 HKT 1970" which is incorrect.

      It seems that it uses, by default, "1970" as year if the date format does not contain "year" part.

      Is it a bug in this function?

      Thanks
        • 1. Re: SimpleDateFormat.parse() generate error
          807591
          In general, the chances that what you think is a Java error is in fact a Java error: 0.00001%
          The chances that you are misunderstanding Java and have a bug in your code: 99.9999%

          Had you looked at the Date API and simply searched on the string "1970", your mystery would be solved.
          • 2. Re: SimpleDateFormat.parse() generate error
            800645
            avoid to use setlenient and try putting the date in the correct format:

            SimpleDateFormat clSdf=new SimpleDateFormat("MMM dd HH:mm yyyy");

            the setLenient makes the parser try to parse with heuristic parsing, but it might not work in all cases.

            And it's not a bug that the year is 1970. It's part of the definition of the Date class:

            http://java.sun.com/j2se/1.4.2/docs/api/java/util/Date.html#getTime()

            and if that is the default, and there were no Feb 29 day in 1970.... you get a Null

            Regards

            Edited by: hjuarez on Mar 5, 2008 4:32 AM
            • 3. Re: SimpleDateFormat.parse() generate error
              807591
              Actually, I use common-net-1.4.1 FTPClient class to get a list of file/directory from FTP Server. The timestamp of the file returned from FTP Server is in "MMM d HH:mm" format if the file is not older than one year. If the file is older than one year, the timestamp of the file returned from FTP Server is in "MMM d yyyy" format which can be parsed correctly.

              I am sure that my program has no bug because it runs for nearly 2.5 years. It only generated problem on Feb 29 this year.
              • 4. Re: SimpleDateFormat.parse() generate error
                807591
                I found SimpleDateFormat error, u can easyly check it, just run my code:
                import java.text.ParsePosition;
                import java.text.SimpleDateFormat;
                import java.util.Date;
                
                public class TestDate {
                 private static void log(String s) {
                    System.out.print(s);
                 }
                 private static void logln(String s) {
                    log(s);
                    log("\n");
                 }
                
                 public static void main(String[] s) {
                     String pattern="dd.MM.yyyy";
                     SimpleDateFormat sdf = new SimpleDateFormat(pattern);
                
                     for (int i=1000;i<3000;i++) {
                            String str="01.04."+i;
                            Date date = sdf.parse(str,new ParsePosition(0));
                            if (!date.toString().contains("Apr 01 00")) {
                                log(date.toString()+" [>"+date.getTime()+"<]");
                                log(" - 1 msecond = ");
                                Date d2=new Date(date.getTime()-1);
                                logln(d2.toString()+" [>"+d2.getTime()+"<]");
                            }
                     }
                
                 }
                }
                i test it on jdk 1.3, jdk 5, jdk 6, and in all cases SimpleDateFormatter result was wrong
                • 5. Re: SimpleDateFormat.parse() generate error
                  Herko_ter_Horst
                  And yet, the bug is in your program, not in the Java library. The fact that your program has been running for 2.5 years is no proof it is correct. The last 2.5 years didn't have a leap day...

                  The problem is that right now you are parsing those "incomplete" dates as if they were in the year 1970. 1970 doesn't have a 29th of February. However, any other date works just fine (except it is in 1970, not 2007/2008).

                  You should find out what year to add to the String you receive from the server (either the current year, or the previous year, most likely).

                  Edit: the original problem has the same cause, it's in the commons-net FTP code: https://issues.apache.org/jira/browse/NET-193. In any case, Date and SimpleDateFormat work as advertised.
                  • 6. Re: SimpleDateFormat.parse() generate error
                    Herko_ter_Horst
                    DATuz, your code doesn't provide any output as show. What is it supposed to test/prove anyway?

                    I've removed the "if" statement and added a throws clause for the ParseException. Now it shows lines like this:
                    Thu Apr 01 00:00:00 CEST 2286 [>9979797600000<] - 1 msecond = Wed Mar 31 23:59:59 CEST 2286 [>9979797599999<]

                    What's wrong with it?
                    • 7. Re: SimpleDateFormat.parse() generate error
                      800645
                      Actually, I use common-net-1.4.1 FTPClient class to get a list of file/directory from FTP Server. The timestamp of the file returned from FTP Server is in "MMM d HH:mm" format if the file is not older than one year. If the file is older than one year, the timestamp of the file returned from FTP Server is in "MMM d yyyy" format which can be parsed correctly.
                      
                      I am sure that my program has no bug because it runs for nearly 2.5 years. It only generated problem on Feb 29 this year. 
                      Your program has been running for years because those years hadn't a feb 29. Feb 29 is the only date which is not in every year, so the last 2 years the program had been defaulting the year as 1970 and it hadn't generated an exception, even if the program was not calculating the time stamp correctly.

                      Just don't get lazy, parse the format that the FTP server returns, if it has the "MMM d HH:mm" format, convert it to the right format and add the current year to the string.

                      Regards