From 1dfee692b087a5962b2b59f8a92e5681cfd6c83e Mon Sep 17 00:00:00 2001 From: Greg Woolsey Date: Sat, 30 Mar 2019 20:13:24 +0000 Subject: [PATCH] #63292 1904 date windowing flag not used for some format cases git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1856648 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/ss/usermodel/DataFormatter.java | 20 ++++++++---- .../poi/ss/usermodel/TestDataFormatter.java | 31 +++++++++++++++++++ 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/src/java/org/apache/poi/ss/usermodel/DataFormatter.java b/src/java/org/apache/poi/ss/usermodel/DataFormatter.java index db61f68d44..e01b336d81 100644 --- a/src/java/org/apache/poi/ss/usermodel/DataFormatter.java +++ b/src/java/org/apache/poi/ss/usermodel/DataFormatter.java @@ -49,6 +49,7 @@ import org.apache.poi.ss.util.NumberToTextConverter; 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; /** @@ -306,10 +307,17 @@ public class DataFormatter implements Observer { 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. @@ -338,7 +346,7 @@ public class DataFormatter implements Observer { 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) ); @@ -788,7 +796,7 @@ public class DataFormatter implements Observer { } return generalNumberFormat; } - + /** * Performs Excel-style date formatting, using the * supplied Date and format @@ -875,7 +883,7 @@ public class DataFormatter implements Observer { // 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); @@ -890,7 +898,7 @@ public class DataFormatter implements Observer { } // else Number - Format numberFormat = getFormat(value, formatIndex, formatString); + Format numberFormat = getFormat(value, formatIndex, formatString, use1904Windowing); if (numberFormat == null) { return String.valueOf(value); } diff --git a/src/testcases/org/apache/poi/ss/usermodel/TestDataFormatter.java b/src/testcases/org/apache/poi/ss/usermodel/TestDataFormatter.java index 014139d88f..d07f8b144d 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/TestDataFormatter.java +++ b/src/testcases/org/apache/poi/ss/usermodel/TestDataFormatter.java @@ -936,6 +936,37 @@ public class TestDataFormatter { 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 { -- 2.39.5