From: Dominik Stadler Date: Wed, 13 Jan 2016 19:46:17 +0000 (+0000) Subject: Regression in version 3.14-beta1: three or four-part formats with locale id cause... X-Git-Tag: REL_3_14_FINAL~77 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=0ba83f7683c7c8925c12a54a4e05be2ef3f3fccd;p=poi.git Regression in version 3.14-beta1: three or four-part formats with locale id cause exceptions when formatting instead of falling back to other formatting git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1724488 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/src/java/org/apache/poi/ss/format/CellFormatPart.java b/src/java/org/apache/poi/ss/format/CellFormatPart.java index 6bd612838c..b4b508fb30 100644 --- a/src/java/org/apache/poi/ss/format/CellFormatPart.java +++ b/src/java/org/apache/poi/ss/format/CellFormatPart.java @@ -140,6 +140,9 @@ public class CellFormatPart { String format = "(?:" + color + ")? # Text color\n" + "(?:\\[" + condition + "\\])? # Condition\n" + + // see https://msdn.microsoft.com/en-ca/goglobal/bb964664.aspx and https://bz.apache.org/ooo/show_bug.cgi?id=70003 + // we ignore these for now though + "(?:\\[\\$-[0-9a-fA-F]+\\])? # Optional locale id, ignored currently\n" + "((?:" + part + ")+) # Format spec\n"; int flags = Pattern.COMMENTS | Pattern.CASE_INSENSITIVE; @@ -360,7 +363,7 @@ public class CellFormatPart { } // Something else inside [] which isn't supported! throw new IllegalArgumentException("Unsupported [] format block '" + - repl + "' in '" + fdesc + "'"); + repl + "' in '" + fdesc + "' with c2: " + c2); case '#': case '?': return CellFormatType.NUMBER; diff --git a/src/java/org/apache/poi/ss/usermodel/DataFormatter.java b/src/java/org/apache/poi/ss/usermodel/DataFormatter.java index 37115feb34..7bd3eaad82 100644 --- a/src/java/org/apache/poi/ss/usermodel/DataFormatter.java +++ b/src/java/org/apache/poi/ss/usermodel/DataFormatter.java @@ -314,13 +314,15 @@ public class DataFormatter implements Observer { CellFormat cfmt = CellFormat.getInstance(formatStr); // CellFormat requires callers to identify date vs not, so do so Object cellValueO = Double.valueOf(cellValue); - if (DateUtil.isADateFormat(formatIndex, formatStr)) { + 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); } // Wrap and return (non-cachable - CellFormat does that) return new CellFormatResultWrapper( cfmt.apply(cellValueO) ); } catch (Exception e) { - logger.log(POILogger.WARN, "Formatting failed as " + formatStr + ", falling back", e); + logger.log(POILogger.WARN, "Formatting failed for format " + formatStr + ", falling back", e); } } diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFDataFormatter.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFDataFormatter.java index 7008524824..7dfd8f3911 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFDataFormatter.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFDataFormatter.java @@ -96,7 +96,11 @@ public final class TestHSSFDataFormatter { "[$-409]mmmmm;@", "[$-409]mmmmm\\-yy;@", "mmmm/d/yyyy;@", - "[$-409]d\\-mmm\\-yyyy;@" + "[$-409]d\\-mmm\\-yyyy;@", + "[$-409]d\\-mmm;[$-3]d\\-mmm;@", // international three-part + "[$-41f]d\\-mmm;[$-41f]d\\-mmm;@", // turkish international three-part + "[$-F40f]d\\-mmm;[$-F40f]d\\-mmm;@", // custom international three-part + "[$-F40f]d\\-mmm;[$-F40f]d\\-mmm;0;@" // custom international four-part }; //valid time formats - all should have 11:23 in output @@ -120,12 +124,16 @@ public final class TestHSSFDataFormatter { "$#,##0.00", "[$-809]#,##0.00", // international format "[$-2]#,##0.00", // international format + "[$-041f]#,##0.00", // international format "0000.00000%", "0.000E+00", "0.00E+00", "[BLACK]0.00;[COLOR 5]##.##", "[>999999]#,,\"M\";[>999]#,\"K\";#", // num/K/M "[>999999]#.000,,\"M\";[>999]#.000,\"K\";#.000", // with decimals + "[$-809]#,##0.00;[$-809]#,##0.00", // two-part international format + "[$-809]#,##0.00;[$-809]#,##0.00;0", // three-part international format + "[$-809]#,##0.00;[$-809]#,##0.00;0;@", // four-part international format }; // invalid date formats -- will throw exception in DecimalFormat ctor diff --git a/src/testcases/org/apache/poi/ss/format/TestCellFormat.java b/src/testcases/org/apache/poi/ss/format/TestCellFormat.java index 97bb6e1e6d..6f4ed58ee2 100644 --- a/src/testcases/org/apache/poi/ss/format/TestCellFormat.java +++ b/src/testcases/org/apache/poi/ss/format/TestCellFormat.java @@ -16,7 +16,7 @@ ==================================================================== */ package org.apache.poi.ss.format; -import static org.junit.Assert.assertEquals; +import static org.junit.Assert.*; import java.io.IOException; import java.text.ParseException; @@ -975,4 +975,40 @@ public class TestCellFormat { //assertEquals(" "+pound+" - ", cfUK.apply(Double.valueOf(0)).text); //assertEquals(" - "+euro+" ", cfFR.apply(Double.valueOf(0)).text); } + + @Test + public void testThreePartComplexFormat1() { + // verify a rather complex format found e.g. in http://wahl.land-oberoesterreich.gv.at/Downloads/bp10.xls + CellFormatPart posPart = new CellFormatPart("[$-F400]h:mm:ss\\ AM/PM"); + assertNotNull(posPart); + assertEquals("1:00:12 AM", posPart.apply(new Date(12345)).text); + + CellFormatPart negPart = new CellFormatPart("[$-F40]h:mm:ss\\ AM/PM"); + assertNotNull(negPart); + assertEquals("1:00:12 AM", posPart.apply(new Date(12345)).text); + + //assertNotNull(new CellFormatPart("_-* \"\"??_-;_-@_-")); + + CellFormat instance = CellFormat.getInstance("[$-F400]h:mm:ss\\ AM/PM;[$-F40]h:mm:ss\\ AM/PM;_-* \"\"??_-;_-@_-"); + assertNotNull(instance); + assertEquals("1:00:12 AM", instance.apply(new Date(12345)).text); + } + + @Test + public void testThreePartComplexFormat2() { + // verify a rather complex format found e.g. in http://wahl.land-oberoesterreich.gv.at/Downloads/bp10.xls + CellFormatPart posPart = new CellFormatPart("dd/mm/yyyy"); + assertNotNull(posPart); + assertEquals("01/01/1970", posPart.apply(new Date(12345)).text); + + CellFormatPart negPart = new CellFormatPart("dd/mm/yyyy"); + assertNotNull(negPart); + assertEquals("01/01/1970", posPart.apply(new Date(12345)).text); + + //assertNotNull(new CellFormatPart("_-* \"\"??_-;_-@_-")); + + CellFormat instance = CellFormat.getInstance("dd/mm/yyyy;dd/mm/yyyy;_-* \"\"??_-;_-@_-"); + assertNotNull(instance); + assertEquals("01/01/1970", instance.apply(new Date(12345)).text); + } } \ No newline at end of file diff --git a/test-data/spreadsheet/at.gv.land-oberoesterreich.www_cps_rde_xbcr_SID-4A1B954F-5C07F98E_ooe_stat_download_bp10.xls b/test-data/spreadsheet/at.gv.land-oberoesterreich.www_cps_rde_xbcr_SID-4A1B954F-5C07F98E_ooe_stat_download_bp10.xls new file mode 100755 index 0000000000..dd0bd53ba0 Binary files /dev/null and b/test-data/spreadsheet/at.gv.land-oberoesterreich.www_cps_rde_xbcr_SID-4A1B954F-5C07F98E_ooe_stat_download_bp10.xls differ