]> source.dussan.org Git - poi.git/commitdiff
Have HSSFDateUtil.isCellDateFormatted make use of HSSFDateUtils.isADateFormat. A...
authorNick Burch <nick@apache.org>
Mon, 6 Aug 2007 13:38:48 +0000 (13:38 +0000)
committerNick Burch <nick@apache.org>
Mon, 6 Aug 2007 13:38:48 +0000 (13:38 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@563129 13f79535-47bb-0310-9956-ffa450edef68

src/documentation/content/xdocs/changes.xml
src/documentation/content/xdocs/status.xml
src/java/org/apache/poi/hssf/usermodel/HSSFCell.java
src/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java
src/java/org/apache/poi/hssf/usermodel/HSSFDateUtil.java
src/testcases/org/apache/poi/hssf/data/DateFormats.xls [new file with mode: 0644]
src/testcases/org/apache/poi/hssf/usermodel/TestHSSFDateUtil.java

index 64fb1d0be5b9bfa982113d6890757508de77f0a5..be1def70bb6448a6767ff0aa254cc0b4b8ce7b19 100644 (file)
     </devs>
 
         <release version="3.0.2-FINAL" date="2007-??-??">
+            <action dev="POI-DEVELOPERS" type="fix">Improvements to HSSFDateUtils.isADateFormat, and have HSSFDateUtil.isCellDateFormatted use this</action>
+            <action dev="POI-DEVELOPERS" type="fix">42999 - [PATCH] - Fix for HSSFPatriarch positioning problems</action>
+            <action dev="POI-DEVELOPERS" type="add">Support for write-protecting a HSSF workbook</action>
             <action dev="POI-DEVELOPERS" type="add">Support for querying, setting and un-setting protection on sheets in a HSSF workbook</action>
+            <action dev="POI-DEVELOPERS" type="add">Initial HSMF (outlook) support</action>
             <action dev="POI-DEVELOPERS" type="fix">Tidy up the javadocs</action>
         </release>
 
index 34694bc30659711b013ed1681ad3a05f3f8f4c24..5fe08dbd44350c71c8ac210daf358e4c2eeb8250 100644 (file)
 
     <changes>
         <release version="3.0.2-FINAL" date="2007-??-??">
+            <action dev="POI-DEVELOPERS" type="fix">Improvements to HSSFDateUtils.isADateFormat, and have HSSFDateUtil.isCellDateFormatted use this</action>
+            <action dev="POI-DEVELOPERS" type="fix">42999 - [PATCH] - Fix for HSSFPatriarch positioning problems</action>
+            <action dev="POI-DEVELOPERS" type="add">Support for write-protecting a HSSF workbook</action>
             <action dev="POI-DEVELOPERS" type="add">Support for querying, setting and un-setting protection on sheets in a HSSF workbook</action>
+            <action dev="POI-DEVELOPERS" type="add">Initial HSMF (outlook) support</action>
             <action dev="POI-DEVELOPERS" type="fix">Tidy up the javadocs</action>
         </release>
 
index 752f598afe6322738453d4b977ab7314922b0d11..ac3943da46fc4e9f2bc5138ebe6b7b6ee028fa67 100644 (file)
@@ -256,6 +256,14 @@ public class HSSFCell
         }
         return retval;
     }
+    
+    /**
+     * Returns the Workbook that this Cell is bound to
+     * @return
+     */
+    protected Workbook getBoundWorkbook() {
+       return book;
+    }
 
     /**
      * set the cell's number within the row (0 based)
index e978642c53ebfd639a5f16e407a72bfc36ba383a..e2725937fa76aa8cd0eef9af9c2d17fdc44623c4 100644 (file)
@@ -18,7 +18,9 @@
 
 package org.apache.poi.hssf.usermodel;
 
+import org.apache.poi.hssf.model.Workbook;
 import org.apache.poi.hssf.record.ExtendedFormatRecord;
+import org.apache.poi.hssf.record.FormatRecord;
 import org.apache.poi.hssf.util.*;
 
 /**
@@ -266,6 +268,17 @@ public class HSSFCellStyle
     {
         return format.getFormatIndex();
     }
+    
+    /**
+     * Get the contents of the format string, by looking up
+     *  the DataFormat against the supplied workbook
+     * @see org.apache.poi.hssf.usermodel.HSSFDataFormat
+     */
+    public String getDataFormatString(Workbook workbook) {
+       HSSFDataFormat format = new HSSFDataFormat(workbook);
+       
+        return format.getFormat(getDataFormat());
+    }
 
     /**
      * set the font for this style
index 2da04e7f49c21e729b370c1501d1dfe8759cfd33..af16204fde3ce74d237a5bdf4569b13f1139f75e 100644 (file)
@@ -159,7 +159,7 @@ public class HSSFDateUtil
      *  non US date formats.
      *  
      * @param formatIndex The index of the format, eg from ExtendedFormatRecord.getFormatIndex
-     * @param formatString The format string
+     * @param formatString The format string, eg from FormatRecord.getFormatString
      * @see #isInternalDateFormat(int)
      */
     public static boolean isADateFormat(int formatIndex, String formatString) {
@@ -173,12 +173,26 @@ public class HSSFDateUtil
                return false;
        }
        
+       String fs = formatString;
+       
        // Translate \- into just -, before matching
-       String fs = formatString.replaceAll("\\\\-","-");
+       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(";@", "");
+       
+       // If it starts with [$-...], then it is a date, but
+       //  who knows what that starting bit is all about
+       fs = fs.replaceAll("\\[\\$\\-.*?\\]", "");
        
        // Otherwise, check it's only made up of:
-       //  y m d - /
-       if(fs.matches("^[ymd\\-/]+$")) {
+       //  y m d - / ,
+       if(fs.matches("^[ymd\\-/]+$")) {
                return true;
        }
        
@@ -222,12 +236,34 @@ public class HSSFDateUtil
      *  Check if a cell contains a date
      *  Since dates are stored internally in Excel as double values 
      *  we infer it is a date if it is formatted as such. 
+     *  @see #isADateFormat(int,string)
      *  @see #isInternalDateFormat(int)
      */
     public static boolean isCellDateFormatted(HSSFCell cell) {
         if (cell == null) return false;
         boolean bDate = false;
         
+        double d = cell.getNumericCellValue();
+        if ( HSSFDateUtil.isValidExcelDate(d) ) {
+            HSSFCellStyle style = cell.getCellStyle();
+            int i = style.getDataFormat();
+            String f = style.getDataFormatString(cell.getBoundWorkbook());
+            bDate = isADateFormat(i, f);
+        }
+        return bDate;
+    }
+    /**
+     *  Check if a cell contains a date, checking only for internal
+     *   excel date formats.
+     *  As Excel stores a great many of its dates in "non-internal"
+     *   date formats, you will not normally want to use this method.
+     *  @see #isADateFormat(int,string)
+     *  @see #isInternalDateFormat(int)
+     */
+    public static boolean isCellInternalDateFormatted(HSSFCell cell) {
+        if (cell == null) return false;
+        boolean bDate = false;
+        
         double d = cell.getNumericCellValue();
         if ( HSSFDateUtil.isValidExcelDate(d) ) {
             HSSFCellStyle style = cell.getCellStyle();
diff --git a/src/testcases/org/apache/poi/hssf/data/DateFormats.xls b/src/testcases/org/apache/poi/hssf/data/DateFormats.xls
new file mode 100644 (file)
index 0000000..6b2c348
Binary files /dev/null and b/src/testcases/org/apache/poi/hssf/data/DateFormats.xls differ
index 174e01972a83e6c66df4be1fad68998afe747e05..c1516f25313c8f7b662c125fa166e3aad6ba983e 100644 (file)
@@ -21,11 +21,15 @@ package org.apache.poi.hssf.usermodel;
 
 import junit.framework.TestCase;
 
+import java.io.FileInputStream;
 import java.util.Date;
 import java.util.Calendar;
 import java.util.GregorianCalendar;
 import java.util.TimeZone;
 
+import org.apache.poi.hssf.model.Workbook;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+
 /**
  * Class TestHSSFDateUtil
  *
@@ -215,6 +219,14 @@ public class TestHSSFDateUtil
                        "dd/mm/yy", "dd/mm/yyyy", "dd/mmm/yy",
                        "dd-mm-yy", "dd-mm-yyyy",
                        "dd\\-mm\\-yy", // Sometimes escaped
+                       
+                       // These crazy ones are valid
+                       "yyyy-mm-dd;@", "yyyy/mm/dd;@",
+                       "dd-mm-yy;@", "dd-mm-yyyy;@",
+                       // These even crazier ones are also valid
+                       // (who knows what they mean though...)
+                       "[$-F800]dddd\\,\\ mmm\\ dd\\,\\ yyyy",
+                       "[$-F900]ddd/mm/yyy",
        };
        for(int i=0; i<formats.length; i++) {
                assertTrue( HSSFDateUtil.isADateFormat(formatId, formats[i]) );
@@ -232,10 +244,73 @@ public class TestHSSFDateUtil
        }
     }
 
+    /**
+     * Test that against a real, test file, we still do everything
+     *  correctly
+     */
+    public void testOnARealFile() throws Exception {
+        String path     = System.getProperty("HSSF.testdata.path");
+        String filename = path + "/DateFormats.xls";
+        POIFSFileSystem fs =
+            new POIFSFileSystem(new FileInputStream(filename));
+        HSSFWorkbook workbook = new HSSFWorkbook(fs);
+        HSSFSheet sheet       = workbook.getSheetAt(0);
+        Workbook wb           = workbook.getWorkbook();
+        
+        HSSFRow  row;
+        HSSFCell cell;
+        HSSFCellStyle style;
+        
+        double aug_10_2007 = 39304.0;
+        
+        // Should have dates in 2nd column
+        // All of them are the 10th of August
+        // 2 US dates, 3 UK dates
+        row  = sheet.getRow(0);
+        cell = row.getCell((short)1);
+        style = cell.getCellStyle();
+        assertEquals(aug_10_2007, cell.getNumericCellValue(), 0.0001);
+        assertEquals("d-mmm-yy", style.getDataFormatString(wb));
+        assertTrue(HSSFDateUtil.isInternalDateFormat(style.getDataFormat()));
+        assertTrue(HSSFDateUtil.isADateFormat(style.getDataFormat(), style.getDataFormatString(wb)));
+        assertTrue(HSSFDateUtil.isCellDateFormatted(cell));
+        
+        row  = sheet.getRow(1);
+        cell = row.getCell((short)1);
+        style = cell.getCellStyle();
+        assertEquals(aug_10_2007, cell.getNumericCellValue(), 0.0001);
+        assertFalse(HSSFDateUtil.isInternalDateFormat(cell.getCellStyle().getDataFormat()));
+        assertTrue(HSSFDateUtil.isADateFormat(style.getDataFormat(), style.getDataFormatString(wb)));
+        assertTrue(HSSFDateUtil.isCellDateFormatted(cell));
+        
+        row  = sheet.getRow(2);
+        cell = row.getCell((short)1);
+        style = cell.getCellStyle();
+        assertEquals(aug_10_2007, cell.getNumericCellValue(), 0.0001);
+        assertTrue(HSSFDateUtil.isInternalDateFormat(cell.getCellStyle().getDataFormat()));
+        assertTrue(HSSFDateUtil.isADateFormat(style.getDataFormat(), style.getDataFormatString(wb)));
+        assertTrue(HSSFDateUtil.isCellDateFormatted(cell));
+        
+        row  = sheet.getRow(3);
+        cell = row.getCell((short)1);
+        style = cell.getCellStyle();
+        assertEquals(aug_10_2007, cell.getNumericCellValue(), 0.0001);
+        assertFalse(HSSFDateUtil.isInternalDateFormat(cell.getCellStyle().getDataFormat()));
+        assertTrue(HSSFDateUtil.isADateFormat(style.getDataFormat(), style.getDataFormatString(wb)));
+        assertTrue(HSSFDateUtil.isCellDateFormatted(cell));
+        
+        row  = sheet.getRow(4);
+        cell = row.getCell((short)1);
+        style = cell.getCellStyle();
+        assertEquals(aug_10_2007, cell.getNumericCellValue(), 0.0001);
+        assertFalse(HSSFDateUtil.isInternalDateFormat(cell.getCellStyle().getDataFormat()));
+        assertTrue(HSSFDateUtil.isADateFormat(style.getDataFormat(), style.getDataFormatString(wb)));
+        assertTrue(HSSFDateUtil.isCellDateFormatted(cell));
+    }
+    
     public static void main(String [] args) {
         System.out
                 .println("Testing org.apache.poi.hssf.usermodel.TestHSSFDateUtil");
         junit.textui.TestRunner.run(TestHSSFDateUtil.class);
     }
-
 }