diff --git a/src/documentation/content/xdocs/changes.xml b/src/documentation/content/xdocs/changes.xml
index 64fb1d0be..be1def70b 100644
--- a/src/documentation/content/xdocs/changes.xml
+++ b/src/documentation/content/xdocs/changes.xml
@@ -36,7 +36,11 @@
+ Improvements to HSSFDateUtils.isADateFormat, and have HSSFDateUtil.isCellDateFormatted use this
+ 42999 - [PATCH] - Fix for HSSFPatriarch positioning problems
+ Support for write-protecting a HSSF workbook
Support for querying, setting and un-setting protection on sheets in a HSSF workbook
+ Initial HSMF (outlook) support
Tidy up the javadocs
diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml
index 34694bc30..5fe08dbd4 100644
--- a/src/documentation/content/xdocs/status.xml
+++ b/src/documentation/content/xdocs/status.xml
@@ -33,7 +33,11 @@
+ Improvements to HSSFDateUtils.isADateFormat, and have HSSFDateUtil.isCellDateFormatted use this
+ 42999 - [PATCH] - Fix for HSSFPatriarch positioning problems
+ Support for write-protecting a HSSF workbook
Support for querying, setting and un-setting protection on sheets in a HSSF workbook
+ Initial HSMF (outlook) support
Tidy up the javadocs
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java
index 752f598af..ac3943da4 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java
@@ -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)
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java b/src/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java
index e978642c5..e2725937f 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java
@@ -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
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFDateUtil.java b/src/java/org/apache/poi/hssf/usermodel/HSSFDateUtil.java
index 2da04e7f4..af16204fd 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFDateUtil.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFDateUtil.java
@@ -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
index 000000000..6b2c3480b
Binary files /dev/null and b/src/testcases/org/apache/poi/hssf/data/DateFormats.xls differ
diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFDateUtil.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFDateUtil.java
index 174e01972..c1516f253 100644
--- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFDateUtil.java
+++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFDateUtil.java
@@ -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