From 107ad2bfef6b47cf641c70342a498ed606013dd5 Mon Sep 17 00:00:00 2001 From: aral-matrix <> Date: Mon, 9 Dec 2024 16:53:22 +0100 Subject: [PATCH] 2024-12-09 bugfix XLDateTime conversions, issue #299 --- OpenXLSX/sources/XLDateTime.cpp | 14 +++++++------- README.md | 17 +++++++++++------ 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/OpenXLSX/sources/XLDateTime.cpp b/OpenXLSX/sources/XLDateTime.cpp index 5fc253ed..e29c5bb3 100644 --- a/OpenXLSX/sources/XLDateTime.cpp +++ b/OpenXLSX/sources/XLDateTime.cpp @@ -18,7 +18,7 @@ namespace */ bool isLeapYear(int year) { - if (year == 1900) return true; + if (year == 1900) return true; // historical Excel Date error inherited from older spreadsheet apps if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) return true; return false; } @@ -86,7 +86,7 @@ namespace OpenXLSX */ XLDateTime::XLDateTime(double serial) : m_serial(serial) { - if (serial < 1.0) throw XLDateTimeError("Excel date/time serial number is invalid (must be >= 1.0.)"); + if (serial < 1.0) throw XLDateTimeError("Excel date/time serial number is invalid (must be >= 1.0.)"); // don't permit dates before 1900-01-01T00:00:00.000 } /** @@ -129,7 +129,7 @@ namespace OpenXLSX { // There are 86400 seconds in a day // There are 25569 days between 1/1/1970 and 30/12/1899 (the epoch used by Excel) - m_serial = static_cast(unixtime) / 86400 + 25569; + m_serial = ( static_cast(unixtime) / 86400 ) + 25569; } /** @@ -207,8 +207,8 @@ namespace OpenXLSX // ===== Count the number of whole years since 1900. while (true) { - const auto days = (isLeapYear(result.tm_year + 1900) ? 366 : 365); - if (days > serial) break; + const int days = (isLeapYear(result.tm_year + 1900) ? 366 : 365); + if (days >= serial) break; // 2024-12-09 BUGFIX: break on days >= serial (was: days > serial, getting last days of a year wrong) serial -= days; ++result.tm_year; } @@ -219,8 +219,8 @@ namespace OpenXLSX // ===== Count the number of whole months in the year. while (true) { - auto days = daysInMonth(result.tm_mon + 1, 1900 + result.tm_year); - if (days > serial) break; + int days = daysInMonth(result.tm_mon + 1, 1900 + result.tm_year); + if (days >= serial) break; // 2024-12-09 BUGFIX: break on days >= serial (was: days > serial, getting last days of a month wrong) serial -= days; ++result.tm_mon; } diff --git a/README.md b/README.md index 2a15ddfc..d0aa81c1 100644 --- a/README.md +++ b/README.md @@ -3,17 +3,14 @@ OpenXLSX is a C++ library for reading, writing, creating and modifying Microsoft Excel® files, with the .xlsx format. -## (aral-matrix) 26 November 2024 - NOTE: "Releases" are severely outdated - do not use them +## (aral-matrix) 09 December 2024 - Bugfix for XLDateTime (hopefully final ;) As the heading says - the latest "Release" that is shown on https://github.com/troldal/OpenXLSX/releases is from 2021-11-06, and severely outdated - please pull / download the latest SW version directly from the repository in its current state. Link for those that do not want to use ```git```: https://github.com/troldal/OpenXLSX/archive/refs/heads/master.zip -## (aral-matrix) 27 October 2024 - Bugfix for XLSheet::mergeCells -It appears that MS Office does not tolerate any formatting XML nodes prior to the `````` XML node - in order to get rid of an according error message, the latest commit modifies the ```XLSheet::merges``` function to insert a newly created `````` node directly after the `````` node. - -## (aral-matrix) 25 October 2024 - Added default values to a newly created XLCellFormat (from XLCellFormats::create, when no template is provided) +Reviewed the XLDateTime code in response to https://github.com/troldal/OpenXLSX/issues/299 and fixed a bug that I think I may have introduced myself. Apologies, dates should now correctly construct from ```double```, ```struct tm``` and ```time_t``` and convert back to ```struct tm```. -These missing defaults could lead to followup errors when any style index of this cell was later assumed valid to access said style by index (Exception if the index was not in a valid range). All style indexes available in a cell format are now zero-initialized (with no assumptions what the style with index 0 may be configured as, normally it's defaults - if you want to be sure, provide a cell with a known format as copyFrom template to XLCellFormats::create). +## Change history Change history is found in the [detailed change log](#detailed-change-log). @@ -442,6 +439,14 @@ transition to the new version instead.

Detailed change log

+### (aral-matrix) 27 October 2024 - Bugfix for XLSheet::mergeCells + +It appears that MS Office does not tolerate any formatting XML nodes prior to the `````` XML node - in order to get rid of an according error message, the latest commit modifies the ```XLSheet::merges``` function to insert a newly created `````` node directly after the `````` node. + +### (aral-matrix) 25 October 2024 - Added default values to a newly created XLCellFormat (from XLCellFormats::create, when no template is provided) + +These missing defaults could lead to followup errors when any style index of this cell was later assumed valid to access said style by index (Exception if the index was not in a valid range). All style indexes available in a cell format are now zero-initialized (with no assumptions what the style with index 0 may be configured as, normally it's defaults - if you want to be sure, provide a cell with a known format as copyFrom template to XLCellFormats::create). + ### (aral-matrix) 14 October 2024 - added basic support to suppress harmless warnings (e.g. about XLSX unsupported features) * ```XLDocument.hpp```: added ```showWarnings()``` (default setting) and ```suppressWarnings()``` * ```XLStyles.hpp```: added ```suppressWarnings``` parameter to constructor (default: ```false```)