Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4808839

Enhance efficiency of java.sql.Date valueOf()

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Duplicate
    • Icon: P4 P4
    • None
    • 1.4.0
    • core-libs
    • x86
    • windows_2000



      Name: jl125535 Date: 01/27/2003


      FULL PRODUCT VERSION :
      java version "1.4.0"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
      Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)

      A DESCRIPTION OF THE PROBLEM :
      java.sql.Date valueOf() is written making extensive use of
      String's subString and indexOf to parse a JDBC Escaped Date
      string into a java.sql.Date instance. Suggested enhancement
      removes dependence on String and Integer.parseInt() and
      makes one pass through a char buffer extracted from String
      and directly parses the characters into an int array.
      Previous code did little validation of the parsed values,
      suggested enhancement code does quick but complete
      validateion of the parsed values. Current code has a bug in
      it that it will accept "2000-0--1" or "2000-0-0" or "2000-0-"
      and return unpredicatable results.


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      Current source code:
          public static Date valueOf(String s) {
      int year;
      int month;
      int day;
      int firstDash;
      int secondDash;

      if (s == null) throw new java.lang.IllegalArgumentException();

      firstDash = s.indexOf('-');
      secondDash = s.indexOf('-', firstDash+1);
      if ((firstDash > 0) & (secondDash > 0) & (secondDash < s.length()-1)) {
      year = Integer.parseInt(s.substring(0, firstDash)) - 1900;
      month = Integer.parseInt(s.substring(firstDash+1, secondDash)) - 1;
      day = Integer.parseInt(s.substring(secondDash+1));
      } else {
      throw new java.lang.IllegalArgumentException();
      }

      return new Date(year, month, day);
          }

        Suggested enhancement:
          public static Date valueOf(String s) {
      if (s == null) {
      throw new java.lang.IllegalArgumentException();
      }

      char buf[] = s.toCharArray();
      int results[] = {0,0,0};
      int r = 0; // results index to 0
      int i=0; // buf index to 0
      while (i < buf.length) {
      char c = buf[i++];
      if (c == '-') {
      if (r++ >= results.length) {
      throw new java.lang.IllegalArgumentException();
      }
      } else {
      int digit = Character.digit(c, 10);
      if (digit < 0) {
      throw new NumberFormatException(s);
      }
      results[r] = (results[r] * 10) + digit;
      if (results[r] > 9999) {
      // None of the fields should exceed 9999
      throw new NumberFormatException(s);
      }
      }
      }

      // Validate results
      if (
      // Diddn't reach end of buffer
      (i != buf.length) ||
      // Didn't parse all of our int's
      (r != results.length - 1) ||
      // No need to check year, already done above
      // Month is too large
      (results[1] > 11) ||
      // Day out of range
      ((results[2] == 0) || (results[2] > 31))) {
      throw new NumberFormatException(s);
      }

      // Create and return new Date
      return new Date(results[0]-1900, results[1], results[2]);
          }

      ---------- END SOURCE ----------
      (Review ID: 153582)
      ======================================================================

            Unassigned Unassigned
            jleesunw Jon Lee (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: