import org.apache.poi.util.LocaleUtil;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
/**
if(formatStr == null || formatStr.trim().length() == 0) {
return null;
}
- return getFormat(cell.getNumericCellValue(), formatIndex, formatStr);
+ return getFormat(cell.getNumericCellValue(), formatIndex, formatStr, isDate1904(cell));
}
- private Format getFormat(double cellValue, int formatIndex, String formatStrIn) {
+ private boolean isDate1904(Cell cell) {
+ if (cell == null || ! (cell.getSheet().getWorkbook() instanceof XSSFWorkbook) ) {
+ return false;
+ }
+ return ((XSSFWorkbook) cell.getSheet().getWorkbook()).isDate1904();
+ }
+
+ private Format getFormat(double cellValue, int formatIndex, String formatStrIn, boolean use1904Windowing) {
localeChangedObservable.checkForLocaleChange();
// Might be better to separate out the n p and z formats, falling back to p when n and z are not set.
if (DateUtil.isADateFormat(formatIndex, formatStr) &&
// don't try to handle Date value 0, let a 3 or 4-part format take care of it
((Double)cellValueO).doubleValue() != 0.0) {
- cellValueO = DateUtil.getJavaDate(cellValue);
+ cellValueO = DateUtil.getJavaDate(cellValue, use1904Windowing);
}
// Wrap and return (non-cachable - CellFormat does that)
return new CellFormatResultWrapper( cfmt.apply(cellValueO) );
}
return generalNumberFormat;
}
-
+
/**
* Performs Excel-style date formatting, using the
* supplied Date and format
// Is it a date?
if(DateUtil.isADateFormat(formatIndex,formatString)) {
if(DateUtil.isValidExcelDate(value)) {
- Format dateFormat = getFormat(value, formatIndex, formatString);
+ Format dateFormat = getFormat(value, formatIndex, formatString, use1904Windowing);
if(dateFormat instanceof ExcelStyleDateFormatter) {
// Hint about the raw excel value
((ExcelStyleDateFormatter)dateFormat).setDateToBeFormatted(value);
}
// else Number
- Format numberFormat = getFormat(value, formatIndex, formatString);
+ Format numberFormat = getFormat(value, formatIndex, formatString, use1904Windowing);
if (numberFormat == null) {
return String.valueOf(value);
}
String value = df.formatCellValue(cell, wb.getCreationHelper().createFormulaEvaluator());
assertEquals("-130", value);
}
+
+ /**
+ * Bug #63292
+ */
+ @Test
+ public void test1904With4PartFormat() {
+ Date date = new Date();
+ int formatIndex = 105;
+ String formatString1 = "[$-F400]m/d/yy h:mm:ss\\ AM/PM";
+ String formatString4 = "[$-F400]m/d/yy h:mm:ss\\ AM/PM;[$-F400]m/d/yy h:mm:ss\\ AM/PM;_-* \"\"??_-;_-@_-";
+
+ String s1900, s1904;
+
+ // These two format calls return the same thing, as expected:
+ // The assertEquals() passes with 1-part format
+ s1900 = format(date, formatIndex, formatString1, false);
+ s1904 = format(date, formatIndex, formatString1, true);
+ assertEquals(s1900, s1904); // WORKS
+
+ // These two format calls should return the same thing but don't:
+ // It fails with 4-part format because the call to CellFormat ignores 'use1904Windowing'
+ s1900 = format(date, formatIndex, formatString4, false);
+ s1904 = format(date, formatIndex, formatString4, true);
+ assertEquals(s1900, s1904); // FAILS before fix for #63292
+ }
+
+ private String format(Date date, int formatIndex, String formatString, boolean use1904Windowing) {
+ DataFormatter formatter = new DataFormatter();
+ double n = DateUtil.getExcelDate(date, use1904Windowing);
+ return formatter.formatRawCellContents(n, formatIndex, formatString, use1904Windowing);
+ }
@Test
public void testConcurrentCellFormat() throws Exception {