Have HSSFDateUtil.isCellDateFormatted make use of HSSFDateUtils.isADateFormat. A few improvements to isADateFormat, and to HSSFCellStyle to allow calling of it. Plus tests

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@563129 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2007-08-06 13:38:48 +00:00
parent 0171d85885
commit d03f88c96b
7 changed files with 145 additions and 5 deletions

View File

@ -36,7 +36,11 @@
</devs> </devs>
<release version="3.0.2-FINAL" date="2007-??-??"> <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">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> <action dev="POI-DEVELOPERS" type="fix">Tidy up the javadocs</action>
</release> </release>

View File

@ -33,7 +33,11 @@
<changes> <changes>
<release version="3.0.2-FINAL" date="2007-??-??"> <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">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> <action dev="POI-DEVELOPERS" type="fix">Tidy up the javadocs</action>
</release> </release>

View File

@ -256,6 +256,14 @@ public class HSSFCell
} }
return retval; 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) * set the cell's number within the row (0 based)

View File

@ -18,7 +18,9 @@
package org.apache.poi.hssf.usermodel; 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.ExtendedFormatRecord;
import org.apache.poi.hssf.record.FormatRecord;
import org.apache.poi.hssf.util.*; import org.apache.poi.hssf.util.*;
/** /**
@ -266,6 +268,17 @@ public class HSSFCellStyle
{ {
return format.getFormatIndex(); 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 * set the font for this style

View File

@ -159,7 +159,7 @@ public class HSSFDateUtil
* non US date formats. * non US date formats.
* *
* @param formatIndex The index of the format, eg from ExtendedFormatRecord.getFormatIndex * @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) * @see #isInternalDateFormat(int)
*/ */
public static boolean isADateFormat(int formatIndex, String formatString) { public static boolean isADateFormat(int formatIndex, String formatString) {
@ -173,12 +173,26 @@ public class HSSFDateUtil
return false; return false;
} }
String fs = formatString;
// Translate \- into just -, before matching // 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: // Otherwise, check it's only made up of:
// y m d - / // y m d - / ,
if(fs.matches("^[ymd\\-/]+$")) { if(fs.matches("^[ymd\\-/, ]+$")) {
return true; return true;
} }
@ -222,12 +236,34 @@ public class HSSFDateUtil
* Check if a cell contains a date * Check if a cell contains a date
* Since dates are stored internally in Excel as double values * Since dates are stored internally in Excel as double values
* we infer it is a date if it is formatted as such. * we infer it is a date if it is formatted as such.
* @see #isADateFormat(int,string)
* @see #isInternalDateFormat(int) * @see #isInternalDateFormat(int)
*/ */
public static boolean isCellDateFormatted(HSSFCell cell) { public static boolean isCellDateFormatted(HSSFCell cell) {
if (cell == null) return false; if (cell == null) return false;
boolean bDate = 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(); double d = cell.getNumericCellValue();
if ( HSSFDateUtil.isValidExcelDate(d) ) { if ( HSSFDateUtil.isValidExcelDate(d) ) {
HSSFCellStyle style = cell.getCellStyle(); HSSFCellStyle style = cell.getCellStyle();

Binary file not shown.

View File

@ -21,11 +21,15 @@ package org.apache.poi.hssf.usermodel;
import junit.framework.TestCase; import junit.framework.TestCase;
import java.io.FileInputStream;
import java.util.Date; import java.util.Date;
import java.util.Calendar; import java.util.Calendar;
import java.util.GregorianCalendar; import java.util.GregorianCalendar;
import java.util.TimeZone; import java.util.TimeZone;
import org.apache.poi.hssf.model.Workbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
/** /**
* Class TestHSSFDateUtil * 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/mmm/yy",
"dd-mm-yy", "dd-mm-yyyy", "dd-mm-yy", "dd-mm-yyyy",
"dd\\-mm\\-yy", // Sometimes escaped "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++) { for(int i=0; i<formats.length; i++) {
assertTrue( HSSFDateUtil.isADateFormat(formatId, formats[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) { public static void main(String [] args) {
System.out System.out
.println("Testing org.apache.poi.hssf.usermodel.TestHSSFDateUtil"); .println("Testing org.apache.poi.hssf.usermodel.TestHSSFDateUtil");
junit.textui.TestRunner.run(TestHSSFDateUtil.class); junit.textui.TestRunner.run(TestHSSFDateUtil.class);
} }
} }