Skip to content

Commit

Permalink
Complete Breakup Of Calculation/DateTime Functions (#1937)
Browse files Browse the repository at this point in the history
* Complete Breakup Of Calculation/DateTime Functions

In conjunction with parallel breakups happening in other areas of Calculation, this change breaks up all the DateTime functions into their own classes. All methods remaining in DateTime itself have a doc block deprecation notice, and consist only of stub code to call the replacement methods. Coverage of DateTime itself and all the replacement methods is 100%.

There is only one substantive change to the code (see next paragraph). Among the non-substantive changes, it now adopts the same parsing technique (throwing and catching exceptions) already in use in Engineering and MathTrig. Boolean parameters are allowed in lieu of numbers when Excel allows them. Most of the code changes involve refactoring due to the need to avoid Scrutinizer "complexity" failures in what it will consider to be new methods.

Issue #1936 was opened just as I was staging this. It is now fixed. One existing WORKDAY test was wrong (noted in a comment in the test data file), and a bunch of new tests are added.

I found it confusing to use DateTime as a node of the the class name since most of the methods invoke native DateTime methods. So, everything is moved to directory DateTimeExcel, and that is what is used in the class names.

There are several follow-up activities that I am planning to undertake if this PR is merged.

- ODS supports dates well before 1900. There are exactly 2 assertions for this functionality. More are needed (and some functions might have to change to accept this).
- WEEKDAY has some poorly documented extra options for "style" which are not yet implemented.
- Most tests have been changed to use a formula as entered on a spreadsheet rather than a direct call to the method which implements the formula. There are 3 exceptions at this time. WORKDAY and NETWORKDAYS, which include arrays as part of their parameters, are more complicated than most. YEARFRAC was just too large to deal with now.
- There are direct calls to the now-deprecated methods in both source code and tests, mostly in Financial code, but possibly in others as well. These need to be changed.
- Some constants, none "officially" documented, remain in the original class. These should be either deleted or marked deprecated. I wasn't sure if deprecation was even possible (or desirable), and did not want that to be something which would cause Scrutinizer to fail the change.

* Deprecate Now-unused Constants, Fix Yearfrac bug, Change 3 Tests

Add new DateTime/Constants class, initially populated with constants used in Weeknum.

MS has another inconsistency with how it handles null cells in Yearfrac. Change PhpSpreadsheet to behave compatibly with this bug.

I have modified YearFrac, WorkDay, and NetworkDays tests to be more to my liking. Many tests added to YearFrac because of the bug above. Only minor modifications to the existing tests for the others.
  • Loading branch information
oleibman authored Mar 21, 2021
1 parent b87d78b commit 9beacd2
Show file tree
Hide file tree
Showing 76 changed files with 3,871 additions and 3,748 deletions.
46 changes: 23 additions & 23 deletions src/PhpSpreadsheet/Calculation/Calculation.php
Original file line number Diff line number Diff line change
Expand Up @@ -755,17 +755,17 @@ class Calculation
],
'DATE' => [
'category' => Category::CATEGORY_DATE_AND_TIME,
'functionCall' => [DateTime::class, 'DATE'],
'functionCall' => [DateTimeExcel\Datefunc::class, 'funcDate'],
'argumentCount' => '3',
],
'DATEDIF' => [
'category' => Category::CATEGORY_DATE_AND_TIME,
'functionCall' => [DateTime::class, 'DATEDIF'],
'functionCall' => [DateTimeExcel\DateDif::class, 'funcDateDif'],
'argumentCount' => '2,3',
],
'DATEVALUE' => [
'category' => Category::CATEGORY_DATE_AND_TIME,
'functionCall' => [DateTime::class, 'DATEVALUE'],
'functionCall' => [DateTimeExcel\DateValue::class, 'funcDateValue'],
'argumentCount' => '1',
],
'DAVERAGE' => [
Expand All @@ -775,17 +775,17 @@ class Calculation
],
'DAY' => [
'category' => Category::CATEGORY_DATE_AND_TIME,
'functionCall' => [DateTime::class, 'DAYOFMONTH'],
'functionCall' => [DateTimeExcel\Day::class, 'funcDay'],
'argumentCount' => '1',
],
'DAYS' => [
'category' => Category::CATEGORY_DATE_AND_TIME,
'functionCall' => [DateTime::class, 'DAYS'],
'functionCall' => [DateTimeExcel\Days::class, 'funcDays'],
'argumentCount' => '2',
],
'DAYS360' => [
'category' => Category::CATEGORY_DATE_AND_TIME,
'functionCall' => [DateTime::class, 'DAYS360'],
'functionCall' => [DateTimeExcel\Days360::class, 'funcDays360'],
'argumentCount' => '2,3',
],
'DB' => [
Expand Down Expand Up @@ -920,7 +920,7 @@ class Calculation
],
'EDATE' => [
'category' => Category::CATEGORY_DATE_AND_TIME,
'functionCall' => [DateTime::class, 'EDATE'],
'functionCall' => [DateTimeExcel\EDate::class, 'funcEDate'],
'argumentCount' => '2',
],
'EFFECT' => [
Expand All @@ -935,7 +935,7 @@ class Calculation
],
'EOMONTH' => [
'category' => Category::CATEGORY_DATE_AND_TIME,
'functionCall' => [DateTime::class, 'EOMONTH'],
'functionCall' => [DateTimeExcel\EoMonth::class, 'funcEoMonth'],
'argumentCount' => '2',
],
'ERF' => [
Expand Down Expand Up @@ -1237,7 +1237,7 @@ class Calculation
],
'HOUR' => [
'category' => Category::CATEGORY_DATE_AND_TIME,
'functionCall' => [DateTime::class, 'HOUROFDAY'],
'functionCall' => [DateTimeExcel\Hour::class, 'funcHour'],
'argumentCount' => '1',
],
'HYPERLINK' => [
Expand Down Expand Up @@ -1501,7 +1501,7 @@ class Calculation
],
'ISOWEEKNUM' => [
'category' => Category::CATEGORY_DATE_AND_TIME,
'functionCall' => [DateTime::class, 'ISOWEEKNUM'],
'functionCall' => [DateTimeExcel\IsoWeekNum::class, 'funcIsoWeekNum'],
'argumentCount' => '1',
],
'ISPMT' => [
Expand Down Expand Up @@ -1681,7 +1681,7 @@ class Calculation
],
'MINUTE' => [
'category' => Category::CATEGORY_DATE_AND_TIME,
'functionCall' => [DateTime::class, 'MINUTE'],
'functionCall' => [DateTimeExcel\Minute::class, 'funcMinute'],
'argumentCount' => '1',
],
'MINVERSE' => [
Expand Down Expand Up @@ -1721,7 +1721,7 @@ class Calculation
],
'MONTH' => [
'category' => Category::CATEGORY_DATE_AND_TIME,
'functionCall' => [DateTime::class, 'MONTHOFYEAR'],
'functionCall' => [DateTimeExcel\Month::class, 'funcMonth'],
'argumentCount' => '1',
],
'MROUND' => [
Expand Down Expand Up @@ -1761,7 +1761,7 @@ class Calculation
],
'NETWORKDAYS' => [
'category' => Category::CATEGORY_DATE_AND_TIME,
'functionCall' => [DateTime::class, 'NETWORKDAYS'],
'functionCall' => [DateTimeExcel\NetworkDays::class, 'funcNetworkDays'],
'argumentCount' => '2-3',
],
'NETWORKDAYS.INTL' => [
Expand Down Expand Up @@ -1821,7 +1821,7 @@ class Calculation
],
'NOW' => [
'category' => Category::CATEGORY_DATE_AND_TIME,
'functionCall' => [DateTime::class, 'DATETIMENOW'],
'functionCall' => [DateTimeExcel\Now::class, 'funcNow'],
'argumentCount' => '0',
],
'NPER' => [
Expand Down Expand Up @@ -2175,7 +2175,7 @@ class Calculation
],
'SECOND' => [
'category' => Category::CATEGORY_DATE_AND_TIME,
'functionCall' => [DateTime::class, 'SECOND'],
'functionCall' => [DateTimeExcel\Second::class, 'funcSecond'],
'argumentCount' => '1',
],
'SEQUENCE' => [
Expand Down Expand Up @@ -2421,12 +2421,12 @@ class Calculation
],
'TIME' => [
'category' => Category::CATEGORY_DATE_AND_TIME,
'functionCall' => [DateTime::class, 'TIME'],
'functionCall' => [DateTimeExcel\Time::class, 'funcTime'],
'argumentCount' => '3',
],
'TIMEVALUE' => [
'category' => Category::CATEGORY_DATE_AND_TIME,
'functionCall' => [DateTime::class, 'TIMEVALUE'],
'functionCall' => [DateTimeExcel\TimeValue::class, 'funcTimeValue'],
'argumentCount' => '1',
],
'TINV' => [
Expand All @@ -2446,7 +2446,7 @@ class Calculation
],
'TODAY' => [
'category' => Category::CATEGORY_DATE_AND_TIME,
'functionCall' => [DateTime::class, 'DATENOW'],
'functionCall' => [DateTimeExcel\Today::class, 'funcToday'],
'argumentCount' => '0',
],
'TRANSPOSE' => [
Expand Down Expand Up @@ -2571,12 +2571,12 @@ class Calculation
],
'WEEKDAY' => [
'category' => Category::CATEGORY_DATE_AND_TIME,
'functionCall' => [DateTime::class, 'WEEKDAY'],
'functionCall' => [DateTimeExcel\WeekDay::class, 'funcWeekDay'],
'argumentCount' => '1,2',
],
'WEEKNUM' => [
'category' => Category::CATEGORY_DATE_AND_TIME,
'functionCall' => [DateTime::class, 'WEEKNUM'],
'functionCall' => [DateTimeExcel\WeekNum::class, 'funcWeekNum'],
'argumentCount' => '1,2',
],
'WEIBULL' => [
Expand All @@ -2591,7 +2591,7 @@ class Calculation
],
'WORKDAY' => [
'category' => Category::CATEGORY_DATE_AND_TIME,
'functionCall' => [DateTime::class, 'WORKDAY'],
'functionCall' => [DateTimeExcel\WorkDay::class, 'funcWorkDay'],
'argumentCount' => '2-3',
],
'WORKDAY.INTL' => [
Expand Down Expand Up @@ -2626,12 +2626,12 @@ class Calculation
],
'YEAR' => [
'category' => Category::CATEGORY_DATE_AND_TIME,
'functionCall' => [DateTime::class, 'YEAR'],
'functionCall' => [DateTimeExcel\Year::class, 'funcYear'],
'argumentCount' => '1',
],
'YEARFRAC' => [
'category' => Category::CATEGORY_DATE_AND_TIME,
'functionCall' => [DateTime::class, 'YEARFRAC'],
'functionCall' => [DateTimeExcel\YearFrac::class, 'funcYearFrac'],
'argumentCount' => '2,3',
],
'YIELD' => [
Expand Down
Loading

0 comments on commit 9beacd2

Please sign in to comment.