Skip to content

Commit 50e9505

Browse files
author
MarkBaker
committed
Implement array argments for the DATE() function sothat we can verify that paired arrays/vectors work with functions that support more than 2 arguments
1 parent dd56463 commit 50e9505

File tree

2 files changed

+70
-3
lines changed
  • src/PhpSpreadsheet/Calculation/DateTimeExcel
  • tests/PhpSpreadsheetTests/Calculation/Functions/DateTime

2 files changed

+70
-3
lines changed

src/PhpSpreadsheet/Calculation/DateTimeExcel/Date.php

+12-3
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@
22

33
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
44

5+
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
56
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
67
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
78
use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDateHelper;
89
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
910

1011
class Date
1112
{
13+
use ArrayEnabled;
14+
1215
/**
1316
* DATE.
1417
*
@@ -24,7 +27,7 @@ class Date
2427
* A Month name or abbreviation (English only at this point) such as 'January' or 'Jan' will still be accepted,
2528
* as will a day value with a suffix (e.g. '21st' rather than simply 21); again only English language.
2629
*
27-
* @param int $year The value of the year argument can include one to four digits.
30+
* @param array|int $year The value of the year argument can include one to four digits.
2831
* Excel interprets the year argument according to the configured
2932
* date system: 1900 or 1904.
3033
* If year is between 0 (zero) and 1899 (inclusive), Excel adds that
@@ -35,7 +38,7 @@ class Date
3538
* 2008.
3639
* If year is less than 0 or is 10000 or greater, Excel returns the
3740
* #NUM! error value.
38-
* @param int $month A positive or negative integer representing the month of the year
41+
* @param array|int $month A positive or negative integer representing the month of the year
3942
* from 1 to 12 (January to December).
4043
* If month is greater than 12, month adds that number of months to
4144
* the first month in the year specified. For example, DATE(2008,14,2)
@@ -44,7 +47,7 @@ class Date
4447
* number of months, plus 1, from the first month in the year
4548
* specified. For example, DATE(2008,-3,2) returns the serial number
4649
* representing September 2, 2007.
47-
* @param int $day A positive or negative integer representing the day of the month
50+
* @param array|int $day A positive or negative integer representing the day of the month
4851
* from 1 to 31.
4952
* If day is greater than the number of days in the month specified,
5053
* day adds that number of days to the first day in the month. For
@@ -57,9 +60,15 @@ class Date
5760
*
5861
* @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object,
5962
* depending on the value of the ReturnDateType flag
63+
* If an array of numbers is passed as the argument, then the returned result will also be an array
64+
* with the same dimensions
6065
*/
6166
public static function fromYMD($year, $month, $day)
6267
{
68+
if (is_array($year) || is_array($month) || is_array($day)) {
69+
return self::evaluateArrayArguments([self::class, __FUNCTION__], $year, $month, $day);
70+
}
71+
6372
$baseYear = SharedDateHelper::getExcelCalendar();
6473

6574
try {

tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateTest.php

+58
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
44

5+
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
56
use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Date;
67

78
class DateTest extends AllSetupTeardown
@@ -56,4 +57,61 @@ public function testDATEwith1904Calendar(): void
5657
$result = Date::fromYMD(1901, 1, 31);
5758
self::assertEquals($result, '#NUM!');
5859
}
60+
61+
/**
62+
* @dataProvider providerDateArray
63+
*/
64+
public function testDateArray(array $expectedResult, string $year, string $month, string $day): void
65+
{
66+
$calculation = Calculation::getInstance();
67+
68+
$formula = "=DATE({$year}, {$month}, {$day})";
69+
$result = $calculation->_calculateFormulaValue($formula);
70+
self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14);
71+
}
72+
73+
public function providerDateArray(): array
74+
{
75+
return [
76+
'row vector year' => [[[44197, 44562, 44927]], '{2021,2022,2023}', '1', '1'],
77+
'column vector year' => [[[44197], [44562], [44927]], '{2021;2022;2023}', '1', '1'],
78+
'matrix year' => [[[43831.00, 44197], [44562, 44927]], '{2020,2021;2022,2023}', '1', '1'],
79+
'row vector month' => [[[44562, 44652, 44743, 44835]], '2022', '{1, 4, 7, 10}', '1'],
80+
'column vector month' => [[[44562], [44652], [44743], [44835]], '2022', '{1; 4; 7; 10}', '1'],
81+
'matrix month' => [[[44562, 44652], [44743, 44835]], '2022', '{1, 4; 7, 10}', '1'],
82+
'row vector day' => [[[44561, 44562]], '2022', '1', '{0,1}'],
83+
'column vector day' => [[[44561], [44562]], '2022', '1', '{0;1}'],
84+
'vectors year and month' => [
85+
[
86+
[44197, 44287, 44378, 44470],
87+
[44562, 44652, 44743, 44835],
88+
[44927, 45017, 45108, 45200],
89+
],
90+
'{2021;2022;2023}',
91+
'{1, 4, 7, 10}',
92+
'1',
93+
],
94+
'vectors year and day' => [
95+
[
96+
[44196, 44197],
97+
[44561, 44562],
98+
[44926, 44927],
99+
],
100+
'{2021;2022;2023}',
101+
'1',
102+
'{0,1}',
103+
],
104+
'vectors month and day' => [
105+
[
106+
[44561, 44562],
107+
[44651, 44652],
108+
[44742, 44743],
109+
[44834, 44835],
110+
],
111+
'2022',
112+
'{1; 4; 7; 10}',
113+
'{0,1}',
114+
],
115+
];
116+
}
59117
}

0 commit comments

Comments
 (0)