Skip to content

Commit

Permalink
2024-12-09 bugfix XLDateTime conversions, issue #299
Browse files Browse the repository at this point in the history
  • Loading branch information
aral-matrix committed Dec 9, 2024
1 parent c512231 commit 107ad2b
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 13 deletions.
14 changes: 7 additions & 7 deletions OpenXLSX/sources/XLDateTime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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
}

/**
Expand Down Expand Up @@ -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<double>(unixtime) / 86400 + 25569;
m_serial = ( static_cast<double>(unixtime) / 86400 ) + 25569;
}

/**
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand Down
17 changes: 11 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 ```<mergeCells>``` 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 ```<mergeCells>``` node directly after the ```<sheetData>``` 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).

Expand Down Expand Up @@ -442,6 +439,14 @@ transition to the new version instead.

<h2 id="detailed-change-log">Detailed change log</h2>

### (aral-matrix) 27 October 2024 - Bugfix for XLSheet::mergeCells

It appears that MS Office does not tolerate any formatting XML nodes prior to the ```<mergeCells>``` 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 ```<mergeCells>``` node directly after the ```<sheetData>``` 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```)
Expand Down

0 comments on commit 107ad2b

Please sign in to comment.