From 1896253fb5715ca6b3933a1d3f2f8cdb3b273c2e Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Thu, 25 Nov 2021 12:45:51 +0000 Subject: [PATCH] [bug-65703] new DataFormatter method: setUse4DigitYearsInAllDateFormats - defaults to false git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1895326 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/ss/usermodel/DataFormatter.java | 39 ++++++++++++++++++- .../poi/ss/usermodel/TestDataFormatter.java | 36 +++++++++++++++++ 2 files changed, 73 insertions(+), 2 deletions(-) diff --git a/poi/src/main/java/org/apache/poi/ss/usermodel/DataFormatter.java b/poi/src/main/java/org/apache/poi/ss/usermodel/DataFormatter.java index ed3a447aab..9f7e8a2baa 100644 --- a/poi/src/main/java/org/apache/poi/ss/usermodel/DataFormatter.java +++ b/poi/src/main/java/org/apache/poi/ss/usermodel/DataFormatter.java @@ -203,8 +203,12 @@ public class DataFormatter { */ private final Map formats = new HashMap<>(); + /** whether CSV friendly adjustments should be made to the formatted text **/ private final boolean emulateCSV; + /** whether years in dates should be displayed with 4 digits even if the formatString specifies only 2 **/ + private boolean use4DigitYearsInAllDateFormats = false; + /** stores the locale valid it the last formatting call */ private Locale locale; @@ -266,6 +270,15 @@ public class DataFormatter { this.emulateCSV = emulateCSV; } + /** + * @param use4DigitYearsInAllDateFormats set to true if you want to have all dates formatted with 4 digit + * years (even if the format associated with the cell specifies just 2) + * @since POI 5.2.0 + */ + public void setUse4DigitYearsInAllDateFormats(boolean use4DigitYearsInAllDateFormats) { + this.use4DigitYearsInAllDateFormats = use4DigitYearsInAllDateFormats; + } + /** * Return a Format for the given cell if one exists, otherwise try to * create one. This method will return {@code null} if any of the @@ -462,10 +475,32 @@ public class DataFormatter { return null; } - + String adjustTo4DigitYearsIfConfigured(String format) { + if (use4DigitYearsInAllDateFormats) { + int ypos2 = format.indexOf("yy"); + if (ypos2 < 0) { + return format; + } else { + int ypos3 = format.indexOf("yyy"); + int ypos4 = format.indexOf("yyyy"); + if (ypos4 == ypos2) { + String part1 = format.substring(0, ypos2 + 4); + String part2 = format.substring(ypos2 + 4); + return part1 + adjustTo4DigitYearsIfConfigured(part2); + } else if (ypos3 == ypos2) { + return format; + } else { + String part1 = format.substring(0, ypos2 + 2); + String part2 = format.substring(ypos2 + 2); + return part1 + "yy" + adjustTo4DigitYearsIfConfigured(part2); + } + } + } + return format; + } private Format createDateFormat(String pFormatStr, double cellValue) { - String formatStr = pFormatStr; + String formatStr = adjustTo4DigitYearsIfConfigured(pFormatStr); formatStr = formatStr.replace("\\-","-"); formatStr = formatStr.replace("\\,",","); formatStr = formatStr.replace("\\.","."); // . is a special regexp char diff --git a/poi/src/test/java/org/apache/poi/ss/usermodel/TestDataFormatter.java b/poi/src/test/java/org/apache/poi/ss/usermodel/TestDataFormatter.java index 9fbae9be49..ebc657bac7 100644 --- a/poi/src/test/java/org/apache/poi/ss/usermodel/TestDataFormatter.java +++ b/poi/src/test/java/org/apache/poi/ss/usermodel/TestDataFormatter.java @@ -1032,6 +1032,42 @@ class TestDataFormatter { formatter.formatRawCellContents(-12.5, -1, "0.0\\%;\\-0.0\\%")); } + @Test + void testAdjustTo4DigitYearsIfConfigured() { + DataFormatter dataFormatter = new DataFormatter(); + assertEquals("d/m/yy", dataFormatter.adjustTo4DigitYearsIfConfigured("d/m/yy")); + + dataFormatter.setUse4DigitYearsInAllDateFormats(true); + assertEquals("d/m/yyyy", dataFormatter.adjustTo4DigitYearsIfConfigured("d/m/yy")); + assertEquals("d/m/yyyy", dataFormatter.adjustTo4DigitYearsIfConfigured("d/m/yyyy")); + //fake case with 3 digit year - just leave format as is + assertEquals("d/m/yyy", dataFormatter.adjustTo4DigitYearsIfConfigured("d/m/yyy")); + + assertEquals("yyyy-mm-dd", dataFormatter.adjustTo4DigitYearsIfConfigured("yy-mm-dd")); + assertEquals("yyyy-mm-dd", dataFormatter.adjustTo4DigitYearsIfConfigured("yyyy-mm-dd")); + + assertEquals("m/d/yyyy h:mm", dataFormatter.adjustTo4DigitYearsIfConfigured("m/d/yy h:mm")); + assertEquals("m/d/yyyy h:mm", dataFormatter.adjustTo4DigitYearsIfConfigured("m/d/yyyy h:mm")); + + assertEquals("h:mm:ss AM/PM", dataFormatter.adjustTo4DigitYearsIfConfigured("h:mm:ss AM/PM")); + + assertEquals("yyyy/mmm/dd yyyy", dataFormatter.adjustTo4DigitYearsIfConfigured("yyyy/mmm/dd yy")); + assertEquals("yyyy/mmm/dd yyyy", dataFormatter.adjustTo4DigitYearsIfConfigured("yy/mmm/dd yy")); + assertEquals("yyyy/mmm/dd yyyy", dataFormatter.adjustTo4DigitYearsIfConfigured("yyyy/mmm/dd yyyy")); + + String formatString4 = "[$-F400]m/d/yy h:mm:ss\\ AM/PM;[$-F400]m/d/yy h:mm:ss\\ AM/PM;_-* \"\"??_-;_-@_-"; + assertEquals(formatString4.replace("yy", "yyyy"), dataFormatter.adjustTo4DigitYearsIfConfigured(formatString4)); + } + + @Test + void testDataFormatterWithAdjustTo4DigitYears() { + DataFormatter dataFormatter = new DataFormatter(); + dataFormatter.setUse4DigitYearsInAllDateFormats(true); + double date = 42747.412892397523; + assertEquals("12/1/2017", + dataFormatter.formatRawCellContents(date, -1, "d/m/yy")); + } + private void doFormatTestSequential(DataFormatter formatter) { for (int i = 0; i < 1_000; i++) { assertTrue(doFormatTest(formatter, 43551.50990171296, "3/27/19 12:14:15 PM", i)); -- 2.39.5