diff --git a/main/HSSF/UserModel/HSSFCell.cs b/main/HSSF/UserModel/HSSFCell.cs
index 2a3eaea87..3fbf909a6 100644
--- a/main/HSSF/UserModel/HSSFCell.cs
+++ b/main/HSSF/UserModel/HSSFCell.cs
@@ -850,44 +850,53 @@ private void CheckFormulaCachedValueType(CellType expectedTypeCode, FormulaRecor
///
/// Get the value of the cell as a date. For strings we throw an exception.
- /// For blank cells we return a null.
+ /// For non-Numeric cells including blank cell we return a null.
///
/// The date cell value.
- public DateTime DateCellValue
+ public DateTime? DateCellValue
{
get
{
- if (cellType == CellType.Blank)
+ if (CellType != CellType.Numeric && CellType != CellType.Formula)
{
- return DateTime.MaxValue;
+ return null;
}
- if (cellType == CellType.String)
- {
- throw new InvalidDataException(
- "You cannot get a date value from a String based cell");
- }
- if (cellType == CellType.Boolean)
- {
- throw new InvalidDataException(
- "You cannot get a date value from a bool cell");
- }
- if (cellType == CellType.Error)
+ double value = this.NumericCellValue;
+ return DateUtil.GetJavaDate(value, book.IsDate1904());
+ }
+ }
+#if NET6_0_OR_GREATER
+ public DateOnly? DateOnlyCellValue
+ {
+ get{
+ if (CellType != CellType.Numeric && CellType != CellType.Formula)
{
- throw new InvalidDataException(
- "You cannot get a date value from an error cell");
+ return null;
}
double value = this.NumericCellValue;
if (book.IsDate1904())
{
- return DateUtil.GetJavaDate(value, true);
+ return DateOnly.FromDateTime(DateUtil.GetJavaDate(value, true));
}
else
{
- return DateUtil.GetJavaDate(value, false);
+ return DateOnly.FromDateTime(DateUtil.GetJavaDate(value, false));
+ }
+ }
+ }
+ public TimeOnly? TimeOnlyCellValue
+ {
+ get{
+ if (CellType != CellType.Numeric && CellType != CellType.Formula)
+ {
+ return null;
}
+ double value = NumericCellValue;
+ bool date1904 = Sheet.Workbook.IsDate1904();
+ return TimeOnly.FromDateTime(DateUtil.GetJavaDate(value, date1904));
}
}
-
+#endif
///
/// Get the value of the cell as a string - for numeric cells we throw an exception.
/// For blank cells we return an empty string.
diff --git a/main/SS/Format/CellFormat.cs b/main/SS/Format/CellFormat.cs
index f0479a9d2..d6672a583 100644
--- a/main/SS/Format/CellFormat.cs
+++ b/main/SS/Format/CellFormat.cs
@@ -292,7 +292,7 @@ public CellFormatResult Apply(ICell c)
{
if (DateUtil.IsValidExcelDate(value))
{
- return Apply(c.DateCellValue, value);
+ return Apply((DateTime)c.DateCellValue, value);
}
else
{
diff --git a/main/SS/UserModel/Cell.cs b/main/SS/UserModel/Cell.cs
index 4a3db1654..f20ba7bcf 100644
--- a/main/SS/UserModel/Cell.cs
+++ b/main/SS/UserModel/Cell.cs
@@ -190,12 +190,21 @@ CellType CellType
double NumericCellValue { get; }
///
- /// Get the value of the cell as a date.
+ /// Get the value of the cell as a date. For non-Numeric cells including blank cell we return a null.
///
/// if the cell type returned by GetCellType() is CELL_TYPE_STRING
/// if the cell value isn't a parsable double
- DateTime DateCellValue { get; }
-
+ DateTime? DateCellValue { get; }
+#if NET6_0_OR_GREATER
+ ///
+ /// Get DateOnly-type cell value
+ ///
+ DateOnly? DateOnlyCellValue { get; }
+ ///
+ /// Get TimeOnly-type cell value
+ ///
+ TimeOnly? TimeOnlyCellValue { get; }
+#endif
///
/// Get the value of the cell RichTextString
///
diff --git a/main/SS/UserModel/DataFormatter.cs b/main/SS/UserModel/DataFormatter.cs
index b9c692635..8a2b9102d 100644
--- a/main/SS/UserModel/DataFormatter.cs
+++ b/main/SS/UserModel/DataFormatter.cs
@@ -842,8 +842,10 @@ private String GetFormattedDateString(ICell cell)
cell.NumericCellValue
);
}
- DateTime d = cell.DateCellValue;
- return PerformDateFormatting(d, dateFormat);
+ var d = cell.DateCellValue;
+ if (d == null)
+ return "";
+ return PerformDateFormatting((DateTime)d, dateFormat);
}
/**
diff --git a/ooxml/XSSF/Streaming/SXSSFCell.cs b/ooxml/XSSF/Streaming/SXSSFCell.cs
index e26f2849a..6ad4a5a95 100644
--- a/ooxml/XSSF/Streaming/SXSSFCell.cs
+++ b/ooxml/XSSF/Streaming/SXSSFCell.cs
@@ -15,6 +15,7 @@ the License. You may obtain a copy of the License at
limitations under the License.
==================================================================== */
using System;
+using System.IO;
using NPOI.SS;
using NPOI.SS.Formula.Eval;
using NPOI.SS.UserModel;
@@ -196,23 +197,51 @@ public int ColumnIndex
return _row.GetCellIndex(this);
}
}
-
- public DateTime DateCellValue
+ ///
+ /// Get DateTime-type cell value
+ ///
+ public DateTime? DateCellValue
{
get
{
- CellType cellType = _value.GetType();
- if (cellType == CellType.Blank)
+ if (CellType != CellType.Numeric && CellType != CellType.Formula)
{
- return new DateTime();
+ return null;
}
-
double value = NumericCellValue;
bool date1904 = Sheet.Workbook.IsDate1904();
- return DateUtil.GetJavaDate(value, date1904);
+ return DateUtil.GetJavaDate(value,date1904);
}
}
-
+#if NET6_0_OR_GREATER
+ ///
+ /// Get DateOnly-type cell value
+ ///
+ public DateOnly? DateOnlyCellValue
+ {
+ get{
+ if (CellType != CellType.Numeric && CellType != CellType.Formula)
+ {
+ return null;
+ }
+ double value = NumericCellValue;
+ bool date1904 = Sheet.Workbook.IsDate1904();
+ return DateOnly.FromDateTime(DateUtil.GetJavaDate(value, date1904));
+ }
+ }
+ public TimeOnly? TimeOnlyCellValue
+ {
+ get{
+ if (CellType != CellType.Numeric && CellType != CellType.Formula)
+ {
+ return null;
+ }
+ double value = NumericCellValue;
+ bool date1904 = Sheet.Workbook.IsDate1904();
+ return TimeOnly.FromDateTime(DateUtil.GetJavaDate(value, date1904));
+ }
+ }
+#endif
public byte ErrorCellValue
{
get
diff --git a/ooxml/XSSF/UserModel/XSSFCell.cs b/ooxml/XSSF/UserModel/XSSFCell.cs
index 803a9ebff..43686ad77 100644
--- a/ooxml/XSSF/UserModel/XSSFCell.cs
+++ b/ooxml/XSSF/UserModel/XSSFCell.cs
@@ -26,6 +26,8 @@ limitations under the License.
using NPOI.Util;
using NPOI.SS.Formula.Eval;
using System.Globalization;
+using System.IO;
+
namespace NPOI.XSSF.UserModel
{
@@ -827,13 +829,13 @@ private CellType GetBaseCellType(bool blankCells)
///
/// Get the value of the cell as a date.
///
- public DateTime DateCellValue
+ public DateTime? DateCellValue
{
get
{
- if (CellType == CellType.Blank)
+ if (CellType != CellType.Numeric && CellType != CellType.Formula)
{
- return DateTime.MinValue;
+ return null;
}
double value = NumericCellValue;
@@ -841,6 +843,33 @@ public DateTime DateCellValue
return DateUtil.GetJavaDate(value, date1904);
}
}
+#if NET6_0_OR_GREATER
+ public DateOnly? DateOnlyCellValue
+ {
+ get{
+ if (CellType != CellType.Numeric && CellType != CellType.Formula)
+ {
+ return null;
+ }
+ double value = NumericCellValue;
+ bool date1904 = Sheet.Workbook.IsDate1904();
+ return DateOnly.FromDateTime(DateUtil.GetJavaDate(value, date1904));
+ }
+ }
+
+ public TimeOnly? TimeOnlyCellValue
+ {
+ get{
+ if (CellType != CellType.Numeric && CellType != CellType.Formula)
+ {
+ return null;
+ }
+ double value = NumericCellValue;
+ bool date1904 = Sheet.Workbook.IsDate1904();
+ return TimeOnly.FromDateTime(DateUtil.GetJavaDate(value, date1904));
+ }
+ }
+#endif
public void SetCellValue(DateTime? value)
{
if (value == null)
diff --git a/testcases/main/HSSF/UserModel/TestHSSFCell.cs b/testcases/main/HSSF/UserModel/TestHSSFCell.cs
index 5ffe0f5b4..53b5eabfa 100644
--- a/testcases/main/HSSF/UserModel/TestHSSFCell.cs
+++ b/testcases/main/HSSF/UserModel/TestHSSFCell.cs
@@ -186,7 +186,7 @@ private static void SetCell(HSSFWorkbook workbook, int rowIdx, int colIdx, DateT
cell.SetCellValue(date);
}
- private static DateTime ReadCell(HSSFWorkbook workbook, int rowIdx, int colIdx)
+ private static DateTime? ReadCell(HSSFWorkbook workbook, int rowIdx, int colIdx)
{
NPOI.SS.UserModel.ISheet sheet = workbook.GetSheetAt(0);
IRow row = sheet.GetRow(rowIdx);
@@ -485,7 +485,7 @@ public void TestCellType()
HSSFCell cell = row.CreateCell(0) as HSSFCell;
cell.SetCellType(CellType.Blank);
- Assert.AreEqual("9999-12-31 23:59:59.999", cell.DateCellValue.ToString("yyyy-MM-dd HH:mm:ss.fff"));
+ Assert.IsNull(cell.DateCellValue);
Assert.IsFalse(cell.BooleanCellValue);
Assert.AreEqual("", cell.ToString());
@@ -520,6 +520,25 @@ public void TestCellType()
cell.SetCellValue((IRichTextString)null);
wb.Close();
}
+
+ [Test]
+ public void TestGetDateTimeCellValue()
+ {
+ HSSFWorkbook wb = new HSSFWorkbook();
+ HSSFSheet sheet = wb.CreateSheet() as HSSFSheet;
+ HSSFRow row = sheet.CreateRow(0) as HSSFRow;
+ HSSFCell cell = row.CreateCell(0) as HSSFCell;
+ cell.SetCellValue(new DateTime(2022, 5, 10, 13, 20, 50));
+ Assert.IsNotNull(cell.DateCellValue);
+ Assert.AreEqual(new DateTime(2022, 5, 10, 13, 20, 50), cell.DateCellValue);
+#if NET6_0_OR_GREATER
+ Assert.AreEqual(new DateOnly(2022, 5, 10), cell.DateOnlyCellValue);
+ Assert.AreEqual(new TimeOnly(13, 20, 50), cell.TimeOnlyCellValue);
+#endif
+ HSSFCell cell2 = row.CreateCell(1) as HSSFCell;
+ cell2.SetCellValue("test");
+ Assert.IsNull(cell2.DateCellValue);
+ }
}
}
\ No newline at end of file
diff --git a/testcases/main/HSSF/UserModel/TestHSSFDateUtil.cs b/testcases/main/HSSF/UserModel/TestHSSFDateUtil.cs
index f17393232..6fc72a6f2 100644
--- a/testcases/main/HSSF/UserModel/TestHSSFDateUtil.cs
+++ b/testcases/main/HSSF/UserModel/TestHSSFDateUtil.cs
@@ -549,7 +549,7 @@ public void TestBug19172()
cell.SetCellValue(valueToTest);
- DateTime returnedValue = cell.DateCellValue;
+ DateTime returnedValue = (DateTime)cell.DateCellValue;
Assert.AreEqual(valueToTest.TimeOfDay, returnedValue.TimeOfDay);
}
diff --git a/testcases/main/SS/UserModel/BaseTestCell.cs b/testcases/main/SS/UserModel/BaseTestCell.cs
index 206c43787..dc5b7eb03 100644
--- a/testcases/main/SS/UserModel/BaseTestCell.cs
+++ b/testcases/main/SS/UserModel/BaseTestCell.cs
@@ -84,13 +84,13 @@ public void TestSetValues()
DateTime dt = DateTime.Now.AddMilliseconds(123456789);
cell.SetCellValue(dt);
- Assert.IsTrue((dt.Ticks - cell.DateCellValue.Ticks) >= -20000);
+ Assert.IsTrue((dt.Ticks - ((DateTime)cell.DateCellValue).Ticks) >= -20000);
Assert.AreEqual(CellType.Numeric, cell.CellType);
AssertProhibitedValueAccess(cell, CellType.Boolean, CellType.String,
CellType.Formula, CellType.Error);
cell.SetCellValue(dt);
- Assert.IsTrue((dt.Ticks - cell.DateCellValue.Ticks) >= -20000);
+ Assert.IsTrue((dt.Ticks - ((DateTime)cell.DateCellValue).Ticks) >= -20000);
Assert.AreEqual(CellType.Numeric, cell.CellType);
AssertProhibitedValueAccess(cell, CellType.Boolean, CellType.String,
CellType.Formula, CellType.Error);
diff --git a/testcases/ooxml/XSSF/UserModel/TestXSSFWorkbook.cs b/testcases/ooxml/XSSF/UserModel/TestXSSFWorkbook.cs
index 0ae3c559f..69c4d59f7 100644
--- a/testcases/ooxml/XSSF/UserModel/TestXSSFWorkbook.cs
+++ b/testcases/ooxml/XSSF/UserModel/TestXSSFWorkbook.cs
@@ -1053,7 +1053,7 @@ public void TestBug56957CloseWorkbook()
// read-only mode works!
workbook = WorkbookFactory.Create(OPCPackage.Open(file, PackageAccess.READ));
- DateTime dateAct = workbook.GetSheetAt(0).GetRow(0).GetCell(0, MissingCellPolicy.CREATE_NULL_AS_BLANK).DateCellValue;
+ var dateAct = workbook.GetSheetAt(0).GetRow(0).GetCell(0, MissingCellPolicy.CREATE_NULL_AS_BLANK).DateCellValue;
Assert.AreEqual(dateExp, dateAct);
workbook.Close();
workbook = null;