* 100% Coverage for Calculation/DateTime
The code in DateTime is now completely covered.
Along the way, some errors were discovered and corrected.
- The tests which have had to be changed at the start of every year are
replaced by more robust equivalents which do not require annual changes.
- Several places in the code where Gnumeric and OpenOffice were thought to differ
from Excel do not appear to have had any justification.
I have left a comment where such code has been removed.
- Use DateTime when possible rather than date, time, or strftime functions to avoid
potential Y2038 problems.
- Some impossible code has been removed, replaced by an explanatory comment.
- NETWORKDAYS had a bug when the start date was Sunday. There had been no tests
of this condition.
- Some functions allow boolean and null arguments where a number is expected.
This is more complicated than the equivalent situations in MathTrig because
the initial date for these calculations can be Day 1 rather than Day 0.
- More testing for dates from 1900-01-01 through the fictitious
everywhere-but-Excel 1900-01-29.
- This showed that there is an additional Excel bug - Excel evaluates
WEEKNUM(emptycell) as 0, which is not a valid result for
WEEKNUM without a second argument.
PhpSpreadsheet now duplicates this bug.
- There is a similar and even worse bug for 1904-01-01 in 1904 calculations.
Weeknum returns 0 for this,
but returns the correct value for arguments of 0 or null.
- DATEVALUE should accept 1900-02-29 (sigh) and relatives.
PhpSpreadsheet now duplicates this bug.
- Testing bootstrap sets default timezone. This appears to be a relic from
the releases of PHP where the unwise decision, subsequenly reversed,
was made to issue messages for
"no default timezone is set" rather than just use a sensible default.
This was a disruptive setting for some of the tests I added.
There is only one test in the entire suite which is default-timezone-dependent.
Setting and resetting of default timezone is moved to that test
(Reader/ODS/ODSTest), and out of bootstrap.
- There had been no testing of NOW() function.
- DATEVALUE test had no tests for 1904 calendar and needs some.
- DATE test changed 1900/1904 calendar in use without restoring it.
- WEEKDAY test had no tests for 1904 calendar and needs some.
- Which revealed a bug in Shared/Date (excelToDateTimeObject was not
recognizing 1904-01-01 as valid when 1904 calendar is in use).
- And an additional bug in that legal 1904-calendar values in the 0.0-1.0
range yielded the same "wrong" answers as 1900-calendar (see "One note" below).
Also the comment for one of the calendar-1904 tests was wrong in attempting
to identify what time of day the fraction represented.
I had wanted to break this up into a set of smaller modules, a process already
started for Engineering and MathTrig.
However the number of source code changes was sufficient that I wanted
a clean delta for this request.
If it is merged, I will work on breaking it up afterwards.
One note - Shared/Date/excelToDateTimeObject, when calendar-1900 is in use,
returns an unexpected result if its argument is between 0 and 1,
which is nominally invalid for that calendar.
It uses a base-1970 calendar in that instance. That check is not justifiable
for calendar-1904, where values in that range are legal,
so I made the check specific to calendar-1900,
and adjusted 3 1904 unit test results accordingly. However, I have to admit that
I don't understand why that check should be made even for calendar-1900.
It certainly doesn't match anything that Excel does.
I would recommend scrapping that code altogether.
If agreed, I would do this as part of the break-up into smaller modules.
Another note -
more controversially, it is clear that PhpSpreadsheet needs to support
the Excel and PHP date formats. Although it requires further study,
I am not convinced that it needs to support Unix timestamp format.
Since that is a potential source of Y2038 problems on 32-bit systems,
I would like to open a PR to deprecate the use of that format.
Please let me know if you are aware of a valid reason to continue to support it.
- Refactoring of the Statistical Conditional functions (`AVERAGEIF()`, `AVERAGEIFS()`, `COUNTIF()`, `COUNTIFS()`, `MAXIFS()` and `MINIFS()` to use the new Database functions codebase.
- Extended unit testing
- Fix handling for null values
- Fixes to wildcard text searches
There's still scope for further improvements to memory usage and performance; but for now the code is stable with all unit tests passing
This issue arose while researching issue #1823. The issue was not a bug;
it just required clarification to the author of how to use the software.
But, while researching, I discovered that loading html into 2
sheets of a spreadsheet has a problem if the html title tag is the same
for the 2 sheets. PhpSpreadsheet would be able to save the resulting file,
but Excel would not be able to read it properly because of the duplicate title.
The worksheet setTitle method allows for disambiguation is such a circumstance.
The html reader passed a parameter indicating "don't disambiguate", but I can't
see any harm in changing that to "disambiguate". An extremely simple fix,
with tests to back it up.
* Enable support for dates and percentages in Excel Database functions, and CountIf/AverageIf/etc
* Enable support for booleans in Excel Database functions
* Refactor the Excel Database functions; and rewrite the query building to fix a bug with complex multi-criteria queries that involve both AND and OR conditions
* Fix handling for empty cells and NULL values in searches
* Expand unit tests; and add TODOs for dates, percentages, and wildcard text comparisons
Advanced Value Binder
- Improved format checking/setting for fractions;
- Better percentage checking;
- Some minor refactoring;
- Improved unit testing
I made a documentation change and noticed that the result when browsed
locally did not quite match what is seen when browsing from the web.
After some research, I found https://github.com/mkdocs/mkdocs/issues/2028
That described my situation well and suggested adding an extra
javascript script to the configuration. This worked exactly as desired
on my local machine. This accounts for the presence of extrajs.js
and mkdocs.yml in this request.
In addition to the display problem, "mkdocs build" generates the
documentation into a directory which is not ignored by git. I added
that directory to .gitignore as part of this request.
Finally, since I don't know how exactly the documentation makes it
to production, I made an insignificant change to one doc file as
a sanity check.
* Start extracting Logical Excel functions into separate groups in dedicated classes
* Extracting remaining Logical Excel functions into separate groups in dedicated classes
* Support 'Forms' for ROMAN Function
This seems like an exceptionally silly thing for MS to have implemented
(Wikipedia on Roman Numerals: "There is no indication this is anything
other than an invention by the programmer").
Nevertheless, we can, and therefore probably should, implement it.
Not that I can implement it by an algorithm - Excel describes the various extra
styles as "more concise", "more concise", "more concise", and "simplified".
Nevertheless, since the universe of potential calls is relatively small,
it can be implemented as a table of values where the new forms would return
a different value than "classic". This table is relatively large, so I have
put it its own member to avoid overhead when the function is needed.
* Move ROMAN To Its Own Class
See discussion in PR #1837
* PHP 8.1 Deprecations
PHP8.1 Unit tests failed. 1 line fixes are available for
- Shared/Font
- Shared/XMLWriter
- Style/Color
- Writer/HTML
The problem is that an error is also reported for a strcmp at
line 272 of Cell/Cell. Not only does that line not invoke strcmp,
there is no strcmp in all of Cell/Cell, so I don't know what to make
of the error message. Oh well, let's fix what can be fixed.
Still dealing with the mysterious PHP8.1 unit test failure in Cell\Cell,
which seems to have something to do with strcmp. The only uses of
strcmp that I can find in src/ are in Calculation. I can't find any
use of it in test/ or samples/. So, if this doesn't fix the problem,
I may have to give up.
* ROUND Accepts null, false, and true as First Parameter
Issue #1789 was addressed by PR #1799. In a follow-up discussion,
it came to light that ROUND was not handling the unexpected case where the
first parameter is an empty cell in the same manner that Excel does.
Subsequent investigation showed that a boolean first parameter is permitted.
I broadened my investigation to include the following related functions.
- ROUNDUP
- ROUNDDOWN
- MROUND
- TRUNC
- INT
- FLOOR
- FLOOR.MATH
- FLOOR.PRECISE
- CEILING
- CEILING.MATH
- CEILING.PRECISE
All of these allow a NULL first parameter, and all except MROUND allow boolean.
For completeness, I will note that all treat null string as invalid.
I suspect there are other functions which permit
similarly unexpected parameters, but I consider them out of scope for this PR.
CEILING.MATH and CEILING.PRECISE were unimplemented, and are now supported
as part of this PR.
The tests for each of these functions have been re-coded, though all the original
test data is still included in the test cases, plus several new cases for each.
The new tests now take place as a user would invoke the functions,
through a spreadsheet cell rather than a
direct call to the appropriate function within Calculation/MathTrig.
Aside from being more realistic, the new tests are also more complete.
For example, FLOOR.MATH can take from 1-3 arguments, and the existing tests
confirmed that the function in Calculation could handle a single argument.
However, the function list in Calculation.php erroneously set the number of
arguments for FLOOR.MATH to exactly 3, so, if a user tried to get the calculated
result of a cell containing FLOOR.MATH(1.2), the result would be an Exception.
Aside from the parameter support, there are a few minor code changes.
Ods, as well as Gnumeric, allows the omission of the second parameter for
FLOAT and CEILING; Excel does not. A potential divide-by-zero error is
avoided in CEILING, FLOOR, and FLOORMATH.
I will note that it would probably be beneficial in terms of maintainability
to break MathTrig up into many individual modules. The same would hold for the
other Calculation modules. I would be willing to look into this if you agree
that it would be worthwhile.
* Extract DELTA() and GESTEP() functions from the Engineering class into a dedicated Comparison classes
Retain the original methods in the Engineering class as stubs for BC, but deprecate them. They will be removed for PHPSpreadsheet v2
Note that unit tests still point to the Engineering class stubs; these should be modified to use the Erf and ErfC classes directly when the stubs are removed
* Extract Permutation functions from the Statistical class into a dedicated Permutations class
Retain the original methods in the Statistical class as stubs for BC, but deprecate them. They will be removed for PHPSpreadsheet v2
Note that unit tests still point to the Statistical class stubs; these should be modified to use the Permutations class directly when the stubs are removed
Also provided a basic implementationof the PERMUTATIONA() Function
* Extract all Error functions from the Engineering class into a dedicated Erf and ErfC classes
Retain the original methods in the Engineering class as stubs for BC, but deprecate them. They will be removed for PHPSpreadsheet v2
Note that unit tests still point to the Engineering class stubs; these should be modified to use the Erf and ErfC classes directly when the stubs are removed
* Reminder that ERF is used (either directly or Indirectly) in some of the statistical functions as well
* Extract all Base Conversion functions from the Engineering class into a dedicated Convert<Base> classes extending from a common ConvertBase class
Retain the original methods in the Engineering class as stubs for BC, but deprecate them. They will be removed for PHPSpreadsheet v2
Note that unit tests still point to the Engineering class stubs; these should be modified to use the Convert<Base> classes directly when the stubs are removed
* Split out into separate base conversion classes, with a ConvertBase class for common methods
* Extract all BitWise functions from the Engineering class into a dedicated BitWise class
Retain the original methods in the Engineering class as stubs for BC, but deprecate them. They will be removed for PHPSpreadsheet v2
Note that unit tests still point to the Engineering class stubs; these should be modified to use the bessel classes directly when the stubs are removed
* Move Bessel function calculations from the Engineering class to a dedicated Engineering\Bessel class
Retain the original methods in the Engineering class as stubs for BC, but deprecate them. They will be removed for PHPSpreadsheet v2
* Some refactoring of the Bessel calculation logic
* Fix callable for ConvertUOM()
* Attempt to provide allow failure for PHP8.1 unit tests
PHP8.1 Tests show as passed despite the errors, and it requires checking the actual output from the run to see what the rea result is; but I can live with that until github provides functionality for a proper allow_failure option
* Stacked Alignment - Use Class Constant Rather than Literal
PR #1580 defined constants for "stacked" alignment in cells.
Using those constants outside of Style/Alignment was beyond the
scope of the original PR, but I said I would get to it.
This PR replaces all uses of literal -165, and appropriate uses of
literal 255, with the named constants, and adds tests to make sure
that the changed code is covered in the test suite.
* use axPos value to determine whether an axis title is mapped to the XaxisLabel or YaxisLabel
* update changelog
* Fix php-cs-fixer violations
Co-authored-by: Darren Maczka <dkm@utk.edu>
Co-authored-by: Mark Baker <mark@lange.demon.co.uk>
* Add support for Google Sheets Exported XLSX Charts
Google Sheets XLSX charts use oneCellAnchor positioning and the data series
do not have the *Cache elements with cached values.
* update CHANGELOG
* Add support for Google Sheets Exported XLSX Charts
Google Sheets XLSX charts use oneCellAnchor positioning and the data series
do not have the *Cache elements with cached values. Because the reader had been
assuming *Cache elements existed as children of strRef and numRef, errors about
the node being deleted were thrown when reading Xlsx exported from Google Sheets.
Co-authored-by: Darren Maczka <dkm@utk.edu>
The attribute `$alignmentXml` given to the private method `readAlignmentStyle` is the alignment XML tag that contains the alignment data itself. But inside that method all data are read from another `alignment` XML tag within that given tag. This redundant child-node access resulted in the following error- / notice-message: `PHP Notice: Trying to access array offset on value of type null in /foo/bar/baz/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/Styles.php on line 146`
These changes remove the redundant child-node access in the method `readAlignmentStyle`.
* Treat inline strings like strings in Open Document because it has no specific inline-string format
* implement data-type error
Co-authored-by: Mark Baker <mark@lange.demon.co.uk>