Skip to content

Commit

Permalink
Merge pull request #1447 from antony-liu/poi/v3.16-patch10
Browse files Browse the repository at this point in the history
poi bug 60031: DataFormatter parses months incorrectly when put at the end of date segment.
  • Loading branch information
tonyqus authored Nov 28, 2024
2 parents dd1ae35 + 869d68d commit 4fd6908
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 62 deletions.
4 changes: 4 additions & 0 deletions main/SS/UserModel/DataFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -685,6 +685,10 @@ Excel displays the month instead of minutes."
}
else
{
if (Char.IsWhiteSpace(c))
{
ms.Clear();
}
sb.Append(c);
}
}
Expand Down
70 changes: 9 additions & 61 deletions testcases/main/HSSF/UserModel/TestHSSFSheet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,29 +17,20 @@ limitations under the License.

namespace TestCases.HSSF.UserModel
{
using System.IO;
using System;
using System.Configuration;
using System.Runtime.InteropServices;
using NPOI.HSSF.UserModel;
using NPOI.DDF;
using NPOI.HSSF.Model;
using NPOI.HSSF.Record;
using NPOI.SS.Util;
using NPOI.DDF;

using TestCases.HSSF;
using NPOI.HSSF.Record.Aggregates;
using TestCases.SS;
using TestCases.SS.UserModel;
using NPOI.SS.UserModel;
using NPOI.Util;
using NPOI.HSSF.Record.AutoFilter;
using System.Collections.Generic;
using System.Collections;
using NPOI.SS.Formula;
using NPOI.HSSF.UserModel;
using NPOI.SS.Formula.PTG;
using NPOI.SS.UserModel;
using NPOI.SS.Util;
using NPOI.Util;
using NUnit.Framework;
using NPOI.SS;
using System;
using System.Collections;
using TestCases.HSSF;
using TestCases.SS.UserModel;

/**
* Tests NPOI.SS.UserModel.Sheet. This Test case is very incomplete at the moment.
Expand Down Expand Up @@ -750,49 +741,6 @@ public void TestAutoSizeColumn()
wb1.Close();
}

[Test]
public void TestAutoSizeDate()
{
IWorkbook wb = new HSSFWorkbook();
ISheet s = wb.CreateSheet("Sheet1");
IRow r = s.CreateRow(0);
r.CreateCell(0).SetCellValue(1);
r.CreateCell(1).SetCellValue(123456);

// Will be sized fairly small
s.AutoSizeColumn((short)0);
s.AutoSizeColumn((short)1);

// Size ranges due to different fonts on different machines
Assert.IsTrue(s.GetColumnWidth(0) > 350, "Single number column too small: " + s.GetColumnWidth(0));
//Assert.IsTrue(s.GetColumnWidth(0) < 550, "Single number column too big: " + s.GetColumnWidth(0));
//Todo: find a algorithm of function SheetUtil.GetColumnWidth to make the test statement above succeed.
Assert.IsTrue(s.GetColumnWidth(0) < 650, "Single number column too big: " + s.GetColumnWidth(0));
Assert.IsTrue(s.GetColumnWidth(1) > 1500, "6 digit number column too small: " + s.GetColumnWidth(1));
Assert.IsTrue(s.GetColumnWidth(1) < 2000, "6 digit number column too big: " + s.GetColumnWidth(1));

// Set a date format
ICellStyle cs = wb.CreateCellStyle();
HSSFDataFormat f = (HSSFDataFormat)wb.CreateDataFormat();
cs.DataFormat = (/*setter*/f.GetFormat("yyyy-mm-dd MMMM hh:mm:ss"));
r.GetCell(0).CellStyle = (/*setter*/cs);
r.GetCell(1).CellStyle = (/*setter*/cs);

Assert.IsTrue(DateUtil.IsCellDateFormatted(r.GetCell(0)));
Assert.IsTrue(DateUtil.IsCellDateFormatted(r.GetCell(1)));

// Should Get much bigger now
s.AutoSizeColumn((short)0);
s.AutoSizeColumn((short)1);

Assert.IsTrue(s.GetColumnWidth(0) > 4750, "Date column too small: " + s.GetColumnWidth(0));
Assert.IsTrue(s.GetColumnWidth(1) > 4750, "Date column too small: " + s.GetColumnWidth(1));
Assert.IsTrue(s.GetColumnWidth(0) < 6500, "Date column too big: " + s.GetColumnWidth(0));
Assert.IsTrue(s.GetColumnWidth(0) < 6500, "Date column too big: " + s.GetColumnWidth(0));

wb.Close();
}


[Test]
public void TestAutoSizeRow()
Expand Down
12 changes: 12 additions & 0 deletions testcases/main/POITestCase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,5 +143,17 @@ public static void TestPassesNow(int bug)
{
Assert.Fail("This test passes now. Please update the unit test and bug " + bug + ".");
}

public static void AssertBetween(String message, int value, int min, int max)
{
Assert.IsTrue(min <= value, message + ": " + value + " is less than the minimum value of " + min);
Assert.IsTrue(value <= max, message + ": " + value + " is greater than the maximum value of " + max);
}

public static void AssertStrictlyBetween(String message, int value, int min, int max)
{
Assert.IsTrue(min < value, message + ": " + value + " is less than or equal to the minimum value of " + min);
Assert.IsTrue(value < max, message + ": " + value + " is greater than or equal to the maximum value of " + max);
}
}
}
39 changes: 39 additions & 0 deletions testcases/main/SS/UserModel/BaseTestSheet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1453,6 +1453,45 @@ public void SetActiveCell()
wb2.Close();
}

[Test]
public void TestAutoSizeDate()
{
IWorkbook wb = _testDataProvider.CreateWorkbook();
ISheet s = wb.CreateSheet("Sheet1");
IRow r = s.CreateRow(0);
r.CreateCell(0).SetCellValue(1);
r.CreateCell(1).SetCellValue(123456);

// for the streaming-variant we need to enable autosize-tracking to make it work
TrackColumnsForAutoSizingIfSXSSF(s);

// Will be sized fairly small
s.AutoSizeColumn((short) 0);
s.AutoSizeColumn((short) 1);

// Size ranges due to different fonts on different machines
POITestCase.AssertBetween("Single number column width", (int) s.GetColumnWidth(0), 350, 570);
POITestCase.AssertBetween("6 digit number column width", (int) s.GetColumnWidth(1), 1500, 2100);

// Set a date format
ICellStyle cs = wb.CreateCellStyle();
IDataFormat f = wb.CreateDataFormat();
cs.DataFormat = (/*setter*/f.GetFormat("yyyy-mm-dd MMMM hh:mm:ss"));
r.GetCell(0).CellStyle = (/*setter*/cs);
r.GetCell(1).CellStyle = (/*setter*/cs);

Assert.IsTrue(DateUtil.IsCellDateFormatted(r.GetCell(0)));
Assert.IsTrue(DateUtil.IsCellDateFormatted(r.GetCell(1)));

// Should Get much bigger now
s.AutoSizeColumn((short) 0);
s.AutoSizeColumn((short) 1);

POITestCase.AssertBetween("Date column width", (int) s.GetColumnWidth(0), 4750, 7300);
POITestCase.AssertBetween("Date column width", (int) s.GetColumnWidth(1), 4750, 7300);

wb.Close();
}
}

}
28 changes: 27 additions & 1 deletion testcases/main/SS/UserModel/TestDataFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,32 @@ public void TestFormulaEvaluation()
Assert.AreEqual("5.6789", formatter.FormatCellValue(cell, evaluator));
wb.Close();
}
}

/**
* bug 60031: DataFormatter parses months incorrectly when put at the end of date segment
*/
[Test]
public void TestBug60031()
{
// 23-08-2016 08:51:01 which is 42605.368761574071 as double will be parsed
// with format "yyyy-dd-MM HH:mm:ss" into "2016-23-51 08:51:01".
DataFormatter dfUS = new DataFormatter(CultureInfo.GetCultureInfo("en-US"));
Assert.AreEqual("2016-23-08 08:51:01", dfUS.FormatRawCellContents(42605.368761574071, -1, "yyyy-dd-MM HH:mm:ss"));
Assert.AreEqual("2016-23 08:51:01 08", dfUS.FormatRawCellContents(42605.368761574071, -1, "yyyy-dd HH:mm:ss MM"));
Assert.AreEqual("2017-12-01 January 09:54:33", dfUS.FormatRawCellContents(42747.412892397523, -1, "yyyy-dd-MM MMMM HH:mm:ss"));

Assert.AreEqual("08", dfUS.FormatRawCellContents(42605.368761574071, -1, "MM"));
Assert.AreEqual("01", dfUS.FormatRawCellContents(42605.368761574071, -1, "ss"));

// From Excel help:
/*
The "m" or "mm" code must appear immediately after the "h" or"hh"
code or immediately before the "ss" code; otherwise, Microsoft
Excel displays the month instead of minutes."
*/
Assert.AreEqual("08", dfUS.FormatRawCellContents(42605.368761574071, -1, "mm"));
Assert.AreEqual("08:51", dfUS.FormatRawCellContents(42605.368761574071, -1, "hh:mm"));
Assert.AreEqual("51:01", dfUS.FormatRawCellContents(42605.368761574071, -1, "mm:ss"));
}
}
}

0 comments on commit 4fd6908

Please sign in to comment.