</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>
<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>
}
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)
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.*;
/**
{
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
* 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) {
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;
}
* 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();
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
*
"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]) );
}
}
+ /**
+ * 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);
}
-
}