From ec2ca1764f8ff4cdb0ba4d6e234f3512ac4df967 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Thu, 10 Feb 2022 12:31:22 +0100 Subject: [PATCH] The `WORKDAY()` function accepts 2 "static" arguments that could be passed as arrays; but also accepts a set of trailing date arguments that are accepted as an array by the splat operator. Only the first two arguments should be tested for returning array values; but the logic still needs to work with the full argument set. Provide a separate "subset" method in the `ArrayEnabled` Trait, that allows a subset of arguments to be tested for array returns. Set up basic tests for `WORKDAY()` --- .../Calculation/ArrayEnabled.php | 21 +++++++++++++ .../Calculation/DateTimeExcel/WorkDay.php | 2 ++ .../Functions/DateTime/WorkDayTest.php | 31 +++++++++++++++++++ 3 files changed, 54 insertions(+) diff --git a/src/PhpSpreadsheet/Calculation/ArrayEnabled.php b/src/PhpSpreadsheet/Calculation/ArrayEnabled.php index bc852415..d2e6f3cf 100644 --- a/src/PhpSpreadsheet/Calculation/ArrayEnabled.php +++ b/src/PhpSpreadsheet/Calculation/ArrayEnabled.php @@ -37,6 +37,27 @@ trait ArrayEnabled self::initialiseHelper($arguments); $arguments = self::$arrayArgumentHelper->arguments(); + return self::processArguments($method, ...$arguments); + } + + /** + * @param mixed ...$arguments + */ + protected static function evaluateArrayArgumentsSubset(callable $method, int $limit, ...$arguments): array + { + self::initialiseHelper(array_slice($arguments, 0, $limit)); + $trailingArguments = array_slice($arguments, $limit); + $arguments = self::$arrayArgumentHelper->arguments(); + $arguments = array_merge($arguments, $trailingArguments); + + return self::processArguments($method, ...$arguments); + } + + /** + * @param mixed ...$arguments + */ + private static function processArguments(callable $method, ...$arguments): array + { if (self::$arrayArgumentHelper->hasArrayArgument() === false) { return [$method(...$arguments)]; } diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/WorkDay.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/WorkDay.php index 271dc610..010a24b5 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/WorkDay.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/WorkDay.php @@ -151,6 +151,7 @@ class WorkDay --$endDate; // Adjust the calculated end date if it falls over a weekend $endDow = self::getWeekDay($endDate, 3); + /** int $endDoW */ if ($endDow >= 5) { $endDate += 4 - $endDow; } @@ -183,6 +184,7 @@ class WorkDay } // Adjust the calculated end date if it falls over a weekend $endDoW = self::getWeekDay($endDate, 3); + /** int $endDoW */ if ($endDoW >= 5) { $endDate += -$endDoW + 4; } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WorkDayTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WorkDayTest.php index 3cfa9219..3b73828f 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WorkDayTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WorkDayTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class WorkDayTest extends AllSetupTeardown { /** @@ -49,4 +51,33 @@ class WorkDayTest extends AllSetupTeardown { return require 'tests/data/Calculation/DateTime/WORKDAY.php'; } + + /** + * @dataProvider providerWorkDayArray + */ + public function testWorkDayArray(array $expectedResult, string $startDate, string $endDays, ?string $holidays): void + { + $calculation = Calculation::getInstance(); + + if ($holidays === null) { + $formula = "=WORKDAY({$startDate}, {$endDays})"; + } else { + $formula = "=WORKDAY({$startDate}, {$endDays}, {$holidays})"; + } + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerWorkDayArray(): array + { + return [ + 'row vector #1' => [[[44595, 44596, 44599]], '{"2022-02-01", "2022-02-02", "2022-02-03"}', '2', null], + 'column vector #1' => [[[44595], [44596], [44599]], '{"2022-02-01"; "2022-02-02"; "2022-02-03"}', '2', null], + 'matrix #1' => [[[44595, 44596], [44599, 44600]], '{"2022-02-01", "2022-02-02"; "2022-02-03", "2022-02-04"}', '2', null], + 'row vector #2' => [[[44595, 44596]], '"2022-02-01"', '{2, 3}', null], + 'column vector #2' => [[[44595], [44596]], '"2022-02-01"', '{2; 3}', null], + 'row vector with Holiday' => [[[44596, 44599]], '"2022-02-01"', '{2, 3}', '{"2022-02-02"}'], + 'row vector with Holidays' => [[[44599, 44600]], '"2022-02-01"', '{2, 3}', '{"2022-02-02", "2022-02-03"}'], + ]; + } }