You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ye...@apache.org on 2009/12/22 08:53:03 UTC

svn commit: r893105 - in /poi/trunk/src: documentation/content/xdocs/status.xml java/org/apache/poi/ss/usermodel/DateUtil.java testcases/org/apache/poi/hssf/usermodel/TestHSSFDateUtil.java

Author: yegor
Date: Tue Dec 22 07:52:55 2009
New Revision: 893105

URL: http://svn.apache.org/viewvc?rev=893105&view=rev
Log:
improved performance of DateUtil.isCellDateFormatted(), see Bugzilla 48425

Modified:
    poi/trunk/src/documentation/content/xdocs/status.xml
    poi/trunk/src/java/org/apache/poi/ss/usermodel/DateUtil.java
    poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFDateUtil.java

Modified: poi/trunk/src/documentation/content/xdocs/status.xml
URL: http://svn.apache.org/viewvc/poi/trunk/src/documentation/content/xdocs/status.xml?rev=893105&r1=893104&r2=893105&view=diff
==============================================================================
--- poi/trunk/src/documentation/content/xdocs/status.xml (original)
+++ poi/trunk/src/documentation/content/xdocs/status.xml Tue Dec 22 07:52:55 2009
@@ -34,6 +34,7 @@
 
     <changes>
         <release version="3.7-SNAPSHOT" date="2010-??-??">
+           <action dev="POI-DEVELOPERS" type="fix">48425 - improved performance of DateUtil.isCellDateFormatted()  </action>
            <action dev="POI-DEVELOPERS" type="fix">47215 - fixed InterfaceEndRecord to tolerate unexpected record contents </action>
            <action dev="POI-DEVELOPERS" type="fix">48415 - improved javadoc on HSSPicture.resize() </action>
            <action dev="POI-DEVELOPERS" type="add">added Ant target to install artifacts in local repository </action>

Modified: poi/trunk/src/java/org/apache/poi/ss/usermodel/DateUtil.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/usermodel/DateUtil.java?rev=893105&r1=893104&r2=893105&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/usermodel/DateUtil.java (original)
+++ poi/trunk/src/java/org/apache/poi/ss/usermodel/DateUtil.java Tue Dec 22 07:52:55 2009
@@ -48,6 +48,13 @@
     private static final Pattern TIME_SEPARATOR_PATTERN = Pattern.compile(":");
 
     /**
+     * The following patterns are used in {@link #isADateFormat(int, String)}
+     */
+    private static final Pattern date_ptrn1 = Pattern.compile("^\\[\\$\\-.*?\\]");
+    private static final Pattern date_ptrn2 = Pattern.compile("^\\[[a-zA-Z]+\\]");
+    private static final Pattern date_ptrn3 = Pattern.compile("^[yYmMdDhHsS\\-/,. :\\\\]+[ampAMP/]*$");
+
+    /**
      * Given a Date, converts it into a double representing its internal Excel representation,
      *   which is the number of days since 1/1/1900. Fractional days represent hours, minutes, and seconds.
      *
@@ -181,6 +188,7 @@
         calendar.set(GregorianCalendar.MILLISECOND, millisecondsInDay);
     }
 
+
     /**
      * Given a format ID and its format String, will check to see if the
      *  format represents a date format or not.
@@ -206,36 +214,62 @@
         }
 
         String fs = formatString;
-
-        // Translate \- into just -, before matching
-        fs = fs.replaceAll("\\\\-","-");
-        // And \, into ,
-        fs = fs.replaceAll("\\\\,",",");
-        // And \. into .
-        fs = fs.replaceAll("\\\\.",".");
-        // And '\ ' into ' '
-        fs = fs.replaceAll("\\\\ "," ");
-
-        // If it end in ;@, that's some crazy dd/mm vs mm/dd
-        //  switching stuff, which we can ignore
-        fs = fs.replaceAll(";@", "");
+        /*
+            Normalize the format string. The code below is equivalent
+            to the following consecutive regexp replacements:
+
+             // Translate \- into just -, before matching
+             fs = fs.replaceAll("\\\\-","-");
+             // And \, into ,
+             fs = fs.replaceAll("\\\\,",",");
+             // And \. into .
+             fs = fs.replaceAll("\\\\\\.",".");
+             // And '\ ' into ' '
+             fs = fs.replaceAll("\\\\ "," ");
+
+             // If it end in ;@, that's some crazy dd/mm vs mm/dd
+             //  switching stuff, which we can ignore
+             fs = fs.replaceAll(";@", "");
+
+             The code above was reworked as suggested in bug 48425:
+             simple loop is more efficient than consecutive regexp replacements.
+         */
+        StringBuilder sb = new StringBuilder();
+        for(int i = 0; i < fs.length(); i++){
+            char c = fs.charAt(i);
+            if(i < fs.length() - 1){
+                char nc = fs.charAt(i + 1);
+                if(c == '\\'){
+                    switch (nc){
+                        case '-':
+                        case ',':
+                        case '.':
+                        case ' ':
+                        case '\\':
+                            //skip current '\' and continue to the next char
+                            continue;
+                    }
+                } else if (c == ';' && nc == '@'){
+                    i++;
+                    //skip ";@" duplets
+                    continue;
+                }
+            }
+            sb.append(c);
+        }
+        fs = sb.toString();
 
         // If it starts with [$-...], then could be a date, but
         //  who knows what that starting bit is all about
-        fs = fs.replaceAll("^\\[\\$\\-.*?\\]", "");
-
+        fs = date_ptrn1.matcher(fs).replaceAll("");
         // If it starts with something like [Black] or [Yellow],
         //  then it could be a date
-        fs = fs.replaceAll("^\\[[a-zA-Z]+\\]", "");
+        fs = date_ptrn2.matcher(fs).replaceAll("");
 
         // Otherwise, check it's only made up, in any case, of:
-        //  y m d h s - / , . :
+        //  y m d h s - \ / , . :
         // optionally followed by AM/PM
-        if(fs.matches("^[yYmMdDhHsS\\-/,. :]+[ampAMP/]*$")) {
-            return true;
-        }
-
-        return false;
+        return date_ptrn3.matcher(fs).matches();
     }
 
     /**

Modified: poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFDateUtil.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFDateUtil.java?rev=893105&r1=893104&r2=893105&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFDateUtil.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFDateUtil.java Tue Dec 22 07:52:55 2009
@@ -26,6 +26,7 @@
 
 import org.apache.poi.hssf.HSSFTestDataSamples;
 import org.apache.poi.hssf.model.InternalWorkbook;
+import org.apache.poi.ss.usermodel.DateUtil;
 
 /**
  * Class TestHSSFDateUtil
@@ -239,6 +240,10 @@
                 "DD-MM-YY", "DD-mm-YYYY",
                 "dd\\-mm\\-yy", // Sometimes escaped
                 "dd.mm.yyyy", "dd\\.mm\\.yyyy",
+                "dd\\ mm\\.yyyy AM", "dd\\ mm\\.yyyy pm",
+                 "dd\\ mm\\.yyyy\\-dd", "[h]:mm:ss",
+
+                //YK: TODO "mm:ss.0" is a built-in date format which is not recognized by DateUtil.isInternalDateFormat
 
                 // These crazy ones are valid
                 "yyyy-mm-dd;@", "yyyy/mm/dd;@",



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org