Skip to content

Commit 4de1245

Browse files
author
MarkBaker
committed
More work on array-enabling date functions
1 parent ca81991 commit 4de1245

File tree

6 files changed

+71
-13
lines changed

6 files changed

+71
-13
lines changed

src/PhpSpreadsheet/Calculation/DateTime.php

+7-7
Original file line numberDiff line numberDiff line change
@@ -278,9 +278,9 @@ public static function TIMEVALUE($timeValue)
278278
* or a standard date string
279279
* @param mixed $endDate Excel date serial value, PHP date/time stamp, PHP DateTime object
280280
* or a standard date string
281-
* @param string $unit
281+
* @param array|string $unit
282282
*
283-
* @return int|string Interval between the dates
283+
* @return array|int|string Interval between the dates
284284
*/
285285
public static function DATEDIF($startDate = 0, $endDate = 0, $unit = 'D')
286286
{
@@ -300,12 +300,12 @@ public static function DATEDIF($startDate = 0, $endDate = 0, $unit = 'D')
300300
* @See DateTimeExcel\Days::between()
301301
* Use the between method in the DateTimeExcel\Days class instead
302302
*
303-
* @param DateTimeInterface|float|int|string $endDate Excel date serial value (float),
303+
* @param array|DateTimeInterface|float|int|string $endDate Excel date serial value (float),
304304
* PHP date timestamp (integer), PHP DateTime object, or a standard date string
305-
* @param DateTimeInterface|float|int|string $startDate Excel date serial value (float),
305+
* @param array|DateTimeInterface|float|int|string $startDate Excel date serial value (float),
306306
* PHP date timestamp (integer), PHP DateTime object, or a standard date string
307307
*
308-
* @return int|string Number of days between start date and end date or an error
308+
* @return array|int|string Number of days between start date and end date or an error
309309
*/
310310
public static function DAYS($endDate = 0, $startDate = 0)
311311
{
@@ -331,7 +331,7 @@ public static function DAYS($endDate = 0, $startDate = 0)
331331
* PHP DateTime object, or a standard date string
332332
* @param mixed $endDate Excel date serial value (float), PHP date timestamp (integer),
333333
* PHP DateTime object, or a standard date string
334-
* @param bool $method US or European Method
334+
* @param array|bool $method US or European Method
335335
* FALSE or omitted: U.S. (NASD) method. If the starting date is
336336
* the last day of a month, it becomes equal to the 30th of the
337337
* same month. If the ending date is the last day of a month and
@@ -343,7 +343,7 @@ public static function DAYS($endDate = 0, $startDate = 0)
343343
* occur on the 31st of a month become equal to the 30th of the
344344
* same month.
345345
*
346-
* @return int|string Number of days between start date and end date
346+
* @return array|int|string Number of days between start date and end date
347347
*/
348348
public static function DAYS360($startDate = 0, $endDate = 0, $method = false)
349349
{

src/PhpSpreadsheet/Calculation/DateTimeExcel/Days360.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class Days360
4646
*/
4747
public static function between($startDate = 0, $endDate = 0, $method = false)
4848
{
49-
if (is_array($endDate) || is_array($startDate) || is_array($method)) {
49+
if (is_array($startDate) || is_array($endDate) || is_array($method)) {
5050
return self::evaluateArrayArguments([self::class, __FUNCTION__], $startDate, $endDate, $method);
5151
}
5252

src/PhpSpreadsheet/Calculation/DateTimeExcel/Difference.php

+14-2
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,37 @@
44

55
use DateInterval;
66
use DateTime;
7+
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
78
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
89
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
910
use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDateHelper;
1011

1112
class Difference
1213
{
14+
use ArrayEnabled;
15+
1316
/**
1417
* DATEDIF.
1518
*
1619
* @param mixed $startDate Excel date serial value, PHP date/time stamp, PHP DateTime object
1720
* or a standard date string
21+
* Or can be an array of date values
1822
* @param mixed $endDate Excel date serial value, PHP date/time stamp, PHP DateTime object
1923
* or a standard date string
20-
* @param string $unit
24+
* Or can be an array of date values
25+
* @param array|string $unit
26+
* Or can be an array of unit values
2127
*
22-
* @return int|string Interval between the dates
28+
* @return array|int|string Interval between the dates
29+
* If an array of values is passed for the $startDate or $endDays,arguments, then the returned result
30+
* will also be an array with matching dimensions
2331
*/
2432
public static function interval($startDate, $endDate, $unit = 'D')
2533
{
34+
if (is_array($startDate) || is_array($endDate) || is_array($unit)) {
35+
return self::evaluateArrayArguments([self::class, __FUNCTION__], $startDate, $endDate, $unit);
36+
}
37+
2638
try {
2739
$startDate = Helpers::getDateValue($startDate);
2840
$endDate = Helpers::getDateValue($endDate);

src/PhpSpreadsheet/Calculation/DateTimeExcel/WorkDay.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class WorkDay
2828
* startDate. A positive value for days yields a future date; a
2929
* negative value yields a past date.
3030
* Or can be an array of int values
31-
* @param mixed $dateArgs
31+
* @param null|mixed $dateArgs
3232
*
3333
* @return array|mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object,
3434
* depending on the value of the ReturnDateType flag
@@ -194,8 +194,8 @@ private static function decrementingArray(float $startDate, float $endDate, arra
194194

195195
private static function getWeekDay(float $date, int $wd): int
196196
{
197-
$result = Week::day($date, $wd);
197+
$result = Functions::scalar(Week::day($date, $wd));
198198

199-
return is_string($result) ? -1 : $result;
199+
return is_int($result) ? $result : -1;
200200
}
201201
}

src/PhpSpreadsheet/Calculation/Functions.php

+18
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,24 @@ public static function flattenArray($array)
608608
return $arrayValues;
609609
}
610610

611+
/**
612+
* @param mixed $value
613+
*
614+
* @return null|mixed
615+
*/
616+
public static function scalar($value)
617+
{
618+
if (!is_array($value)) {
619+
return $value;
620+
}
621+
622+
do {
623+
$value = array_pop($value);
624+
} while (is_array($value));
625+
626+
return $value;
627+
}
628+
611629
/**
612630
* Convert a multi-dimensional array to a simple 1-dimensional array, but retain an element of indexing.
613631
*

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

+28
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

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

5+
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
6+
57
class DateDifTest extends AllSetupTeardown
68
{
79
/**
@@ -22,4 +24,30 @@ public function providerDATEDIF(): array
2224
{
2325
return require 'tests/data/Calculation/DateTime/DATEDIF.php';
2426
}
27+
28+
/**
29+
* @dataProvider providerDateDifArray
30+
*/
31+
public function testDateDifArray(array $expectedResult, string $startDate, string $endDate, ?string $methods): void
32+
{
33+
$calculation = Calculation::getInstance();
34+
35+
if ($methods === null) {
36+
$formula = "=DATEDIF({$startDate}, {$endDate})";
37+
} else {
38+
$formula = "=DATEDIF({$startDate}, {$endDate}, {$methods})";
39+
}
40+
$result = $calculation->_calculateFormulaValue($formula);
41+
self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14);
42+
}
43+
44+
public function providerDateDifArray(): array
45+
{
46+
return [
47+
'row vector #1' => [[[364, 202, '#NUM!']], '{"2022-01-01", "2022-06-12", "2023-07-22"}', '"2022-12-31"', null],
48+
'column vector #1' => [[[364], [362], [359]], '{"2022-01-01"; "2022-01-03"; "2022-01-06"}', '"2022-12-31"', null],
49+
'matrix #1' => [[[365, 266], [139, 1]], '{"2022-01-01", "2022-04-10"; "2022-08-15", "2022-12-31"}', '"2023-01-01"', null],
50+
'column vector with methods' => [[[364, 11], [242, 7], [173, 5]], '{"2022-01-01"; "2022-05-03"; "2022-07-11"}', '"2022-12-31"', '{"D", "M"}'],
51+
];
52+
}
2553
}

0 commit comments

Comments
 (0)