Merge pull request #2573 from PHPOffice/Issue-2551_Array-Enabled-DateTime-Functions
Enable most of the Date/Time functions to accept array arguments
This commit is contained in:
commit
5ab3cbc8db
|
|
@ -575,21 +575,6 @@ parameters:
|
|||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/DateTimeExcel/TimeValue.php
|
||||
|
||||
-
|
||||
message: "#^Binary operation \"/\" between int\\|string and \\(float\\|int\\) results in an error\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/DateTimeExcel/YearFrac.php
|
||||
|
||||
-
|
||||
message: "#^Binary operation \"/\" between int\\|string and 360 results in an error\\.$#"
|
||||
count: 3
|
||||
path: src/PhpSpreadsheet/Calculation/DateTimeExcel/YearFrac.php
|
||||
|
||||
-
|
||||
message: "#^Binary operation \"/\" between int\\|string and 365 results in an error\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/DateTimeExcel/YearFrac.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Engine\\\\Logger\\:\\:writeDebugLog\\(\\) has parameter \\$args with no type specified\\.$#"
|
||||
count: 1
|
||||
|
|
@ -870,6 +855,11 @@ parameters:
|
|||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/Financial.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$year of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTimeExcel\\\\Helpers\\:\\:isLeapYear\\(\\) expects int\\|string, array\\|int\\|string given\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/Financial/Amortization.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\CashFlow\\\\Constant\\\\Periodic\\\\Interest\\:\\:rateNextGuess\\(\\) has no return type specified\\.$#"
|
||||
count: 1
|
||||
|
|
@ -925,11 +915,21 @@ parameters:
|
|||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/Financial/CashFlow/Constant/Periodic/InterestAndPrincipal.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\CashFlow\\\\Variable\\\\NonPeriodic\\:\\:xnpvOrdered\\(\\) should return float\\|string but returns array\\|string\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/Financial/CashFlow/Variable/NonPeriodic.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\CashFlow\\\\Variable\\\\Periodic\\:\\:presentValue\\(\\) has parameter \\$args with no type specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/Financial/CashFlow/Variable/Periodic.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$year of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\Helpers\\:\\:daysPerYear\\(\\) expects int\\|string, array\\|int\\|string given\\.$#"
|
||||
count: 3
|
||||
path: src/PhpSpreadsheet/Calculation/Financial/Coupons.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\Depreciation\\:\\:validateCost\\(\\) has parameter \\$cost with no type specified\\.$#"
|
||||
count: 1
|
||||
|
|
@ -975,11 +975,71 @@ parameters:
|
|||
count: 2
|
||||
path: src/PhpSpreadsheet/Calculation/Financial/Dollar.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\Securities\\\\AccruedInterest\\:\\:atMaturity\\(\\) should return float\\|string but returns array\\|string\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/Financial/Securities/AccruedInterest.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\Securities\\\\AccruedInterest\\:\\:periodic\\(\\) should return float\\|string but returns array\\|string\\.$#"
|
||||
count: 2
|
||||
path: src/PhpSpreadsheet/Calculation/Financial/Securities/AccruedInterest.php
|
||||
|
||||
-
|
||||
message: "#^Binary operation \"/\" between float\\|string and float\\|string results in an error\\.$#"
|
||||
count: 2
|
||||
path: src/PhpSpreadsheet/Calculation/Financial/Securities/Price.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\Securities\\\\Price\\:\\:priceAtMaturity\\(\\) should return float\\|string but returns array\\|string\\.$#"
|
||||
count: 3
|
||||
path: src/PhpSpreadsheet/Calculation/Financial/Securities/Price.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\Securities\\\\Price\\:\\:priceDiscounted\\(\\) should return float\\|string but returns array\\|string\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/Financial/Securities/Price.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\Securities\\\\Price\\:\\:received\\(\\) should return float\\|string but returns array\\|string\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/Financial/Securities/Price.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$year of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\Helpers\\:\\:daysPerYear\\(\\) expects int\\|string, array\\|int\\|string given\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/Financial/Securities/Price.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\Securities\\\\Rates\\:\\:discount\\(\\) should return float\\|string but returns array\\|string\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/Financial/Securities/Rates.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\Securities\\\\Rates\\:\\:interest\\(\\) should return float\\|string but returns array\\|string\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/Financial/Securities/Rates.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\Securities\\\\Yields\\:\\:yieldAtMaturity\\(\\) should return float\\|string but returns array\\|string\\.$#"
|
||||
count: 3
|
||||
path: src/PhpSpreadsheet/Calculation/Financial/Securities/Yields.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\Securities\\\\Yields\\:\\:yieldDiscounted\\(\\) should return float\\|string but returns array\\|string\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/Financial/Securities/Yields.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$year of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\Helpers\\:\\:daysPerYear\\(\\) expects int\\|string, array\\|int\\|string given\\.$#"
|
||||
count: 2
|
||||
path: src/PhpSpreadsheet/Calculation/Financial/Securities/Yields.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$year of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\Helpers\\:\\:daysPerYear\\(\\) expects int\\|string, array\\|int\\|string given\\.$#"
|
||||
count: 3
|
||||
path: src/PhpSpreadsheet/Calculation/Financial/TreasuryBill.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method getTokenSubType\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\FormulaToken\\|null\\.$#"
|
||||
count: 4
|
||||
|
|
@ -1916,7 +1976,7 @@ parameters:
|
|||
path: src/PhpSpreadsheet/Calculation/TextData/Format.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$dateValue of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTimeExcel\\\\DateValue\\:\\:fromString\\(\\) expects string, mixed given\\.$#"
|
||||
message: "#^Parameter \\#1 \\$dateValue of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTimeExcel\\\\DateValue\\:\\:fromString\\(\\) expects array\\|string, mixed given\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/TextData/Format.php
|
||||
|
||||
|
|
@ -1931,7 +1991,7 @@ parameters:
|
|||
path: src/PhpSpreadsheet/Calculation/TextData/Format.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$timeValue of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTimeExcel\\\\TimeValue\\:\\:fromString\\(\\) expects string, mixed given\\.$#"
|
||||
message: "#^Parameter \\#1 \\$timeValue of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTimeExcel\\\\TimeValue\\:\\:fromString\\(\\) expects array\\|string, mixed given\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Calculation/TextData/Format.php
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
namespace PhpOffice\PhpSpreadsheet\Calculation;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Engine\ArrayArgumentHelper;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Engine\ArrayArgumentProcessor;
|
||||
|
||||
trait ArrayEnabled
|
||||
{
|
||||
|
|
@ -37,154 +38,19 @@ trait ArrayEnabled
|
|||
self::initialiseHelper($arguments);
|
||||
$arguments = self::$arrayArgumentHelper->arguments();
|
||||
|
||||
if (self::$arrayArgumentHelper->hasArrayArgument() === false) {
|
||||
return [$method(...$arguments)];
|
||||
}
|
||||
|
||||
if (self::$arrayArgumentHelper->arrayArguments() === 1) {
|
||||
$nthArgument = self::$arrayArgumentHelper->getFirstArrayArgumentNumber();
|
||||
|
||||
return self::evaluateNthArgumentAsArray($method, $nthArgument, ...$arguments);
|
||||
}
|
||||
|
||||
$singleRowVectorIndex = self::$arrayArgumentHelper->getSingleRowVector();
|
||||
$singleColumnVectorIndex = self::$arrayArgumentHelper->getSingleColumnVector();
|
||||
if ($singleRowVectorIndex !== null && $singleColumnVectorIndex !== null) {
|
||||
// Basic logic for a single row vector and a single column vector
|
||||
return self::evaluateVectorPair($method, $singleRowVectorIndex, $singleColumnVectorIndex, ...$arguments);
|
||||
}
|
||||
|
||||
$matrixPair = self::$arrayArgumentHelper->getMatrixPair();
|
||||
if ($matrixPair !== []) {
|
||||
if (
|
||||
(self::$arrayArgumentHelper->isVector($matrixPair[0]) === true &&
|
||||
self::$arrayArgumentHelper->isVector($matrixPair[1]) === false) ||
|
||||
(self::$arrayArgumentHelper->isVector($matrixPair[0]) === false &&
|
||||
self::$arrayArgumentHelper->isVector($matrixPair[1]) === true)
|
||||
) {
|
||||
// Logic for a matrix and a vector (row or column)
|
||||
return self::evaluateVectorMatrixPair($method, $matrixPair, ...$arguments);
|
||||
}
|
||||
// Logic for matrix/matrix, column vector/column vector or row vector/row vector
|
||||
return self::evaluateMatrixPair($method, $matrixPair, ...$arguments);
|
||||
}
|
||||
|
||||
// Still need to work out the logic for more than two array arguments,
|
||||
// For the moment, we're throwing an Exception when we initialise the ArrayArgumentHelper
|
||||
return ['#VALUE!'];
|
||||
return ArrayArgumentProcessor::processArguments(self::$arrayArgumentHelper, $method, ...$arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed ...$arguments
|
||||
*/
|
||||
private static function evaluateVectorMatrixPair(callable $method, array $matrixIndexes, ...$arguments): array
|
||||
protected static function evaluateArrayArgumentsSubset(callable $method, int $limit, ...$arguments): array
|
||||
{
|
||||
$matrix2 = array_pop($matrixIndexes);
|
||||
/** @var array $matrixValues2 */
|
||||
$matrixValues2 = $arguments[$matrix2];
|
||||
$matrix1 = array_pop($matrixIndexes);
|
||||
/** @var array $matrixValues1 */
|
||||
$matrixValues1 = $arguments[$matrix1];
|
||||
self::initialiseHelper(array_slice($arguments, 0, $limit));
|
||||
$trailingArguments = array_slice($arguments, $limit);
|
||||
$arguments = self::$arrayArgumentHelper->arguments();
|
||||
$arguments = array_merge($arguments, $trailingArguments);
|
||||
|
||||
$rows = min(array_map([self::$arrayArgumentHelper, 'rowCount'], [$matrix1, $matrix2]));
|
||||
$columns = min(array_map([self::$arrayArgumentHelper, 'columnCount'], [$matrix1, $matrix2]));
|
||||
|
||||
if ($rows === 1) {
|
||||
$rows = max(array_map([self::$arrayArgumentHelper, 'rowCount'], [$matrix1, $matrix2]));
|
||||
}
|
||||
if ($columns === 1) {
|
||||
$columns = max(array_map([self::$arrayArgumentHelper, 'columnCount'], [$matrix1, $matrix2]));
|
||||
}
|
||||
|
||||
$result = [];
|
||||
for ($rowIndex = 0; $rowIndex < $rows; ++$rowIndex) {
|
||||
for ($columnIndex = 0; $columnIndex < $columns; ++$columnIndex) {
|
||||
$rowIndex1 = self::$arrayArgumentHelper->isRowVector($matrix1) ? 0 : $rowIndex;
|
||||
$columnIndex1 = self::$arrayArgumentHelper->isColumnVector($matrix1) ? 0 : $columnIndex;
|
||||
$value1 = $matrixValues1[$rowIndex1][$columnIndex1];
|
||||
$rowIndex2 = self::$arrayArgumentHelper->isRowVector($matrix2) ? 0 : $rowIndex;
|
||||
$columnIndex2 = self::$arrayArgumentHelper->isColumnVector($matrix2) ? 0 : $columnIndex;
|
||||
$value2 = $matrixValues2[$rowIndex2][$columnIndex2];
|
||||
$arguments[$matrix1] = $value1;
|
||||
$arguments[$matrix2] = $value2;
|
||||
|
||||
$result[$rowIndex][$columnIndex] = $method(...$arguments);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed ...$arguments
|
||||
*/
|
||||
private static function evaluateMatrixPair(callable $method, array $matrixIndexes, ...$arguments): array
|
||||
{
|
||||
$matrix2 = array_pop($matrixIndexes);
|
||||
/** @var array $matrixValues2 */
|
||||
$matrixValues2 = $arguments[$matrix2];
|
||||
$matrix1 = array_pop($matrixIndexes);
|
||||
/** @var array $matrixValues1 */
|
||||
$matrixValues1 = $arguments[$matrix1];
|
||||
|
||||
$result = [];
|
||||
foreach ($matrixValues1 as $rowIndex => $row) {
|
||||
foreach ($row as $columnIndex => $value1) {
|
||||
if (isset($matrixValues2[$rowIndex][$columnIndex]) === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$value2 = $matrixValues2[$rowIndex][$columnIndex];
|
||||
$arguments[$matrix1] = $value1;
|
||||
$arguments[$matrix2] = $value2;
|
||||
|
||||
$result[$rowIndex][$columnIndex] = $method(...$arguments);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed ...$arguments
|
||||
*/
|
||||
private static function evaluateVectorPair(callable $method, int $rowIndex, int $columnIndex, ...$arguments): array
|
||||
{
|
||||
$rowVector = Functions::flattenArray($arguments[$rowIndex]);
|
||||
$columnVector = Functions::flattenArray($arguments[$columnIndex]);
|
||||
|
||||
$result = [];
|
||||
foreach ($columnVector as $column) {
|
||||
$rowResults = [];
|
||||
foreach ($rowVector as $row) {
|
||||
$arguments[$rowIndex] = $row;
|
||||
$arguments[$columnIndex] = $column;
|
||||
|
||||
$rowResults[] = $method(...$arguments);
|
||||
}
|
||||
$result[] = $rowResults;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note, offset is from 1 (for the first argument) rather than from 0.
|
||||
*
|
||||
* @param mixed ...$arguments
|
||||
*/
|
||||
private static function evaluateNthArgumentAsArray(callable $method, int $nthArgument, ...$arguments): array
|
||||
{
|
||||
$values = array_slice($arguments, $nthArgument - 1, 1);
|
||||
/** @var array $values */
|
||||
$values = array_pop($values);
|
||||
|
||||
$result = [];
|
||||
foreach ($values as $value) {
|
||||
$arguments[$nthArgument - 1] = $value;
|
||||
$result[] = $method(...$arguments);
|
||||
}
|
||||
|
||||
return $result;
|
||||
return ArrayArgumentProcessor::processArguments(self::$arrayArgumentHelper, $method, ...$arguments);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4368,6 +4368,12 @@ class Calculation
|
|||
if (($operandData['reference'] === null) && (is_array($operand))) {
|
||||
$rKeys = array_keys($operand);
|
||||
$rowKey = array_shift($rKeys);
|
||||
if (is_array($operand[$rowKey]) === false) {
|
||||
$operandData['value'] = $operand[$rowKey];
|
||||
|
||||
return $operand[$rowKey];
|
||||
}
|
||||
|
||||
$cKeys = array_keys(array_keys($operand[$rowKey]));
|
||||
$colKey = array_shift($cKeys);
|
||||
if (ctype_upper("$colKey")) {
|
||||
|
|
|
|||
|
|
@ -278,9 +278,9 @@ class DateTime
|
|||
* or a standard date string
|
||||
* @param mixed $endDate Excel date serial value, PHP date/time stamp, PHP DateTime object
|
||||
* or a standard date string
|
||||
* @param string $unit
|
||||
* @param array|string $unit
|
||||
*
|
||||
* @return int|string Interval between the dates
|
||||
* @return array|int|string Interval between the dates
|
||||
*/
|
||||
public static function DATEDIF($startDate = 0, $endDate = 0, $unit = 'D')
|
||||
{
|
||||
|
|
@ -300,12 +300,12 @@ class DateTime
|
|||
* @See DateTimeExcel\Days::between()
|
||||
* Use the between method in the DateTimeExcel\Days class instead
|
||||
*
|
||||
* @param DateTimeInterface|float|int|string $endDate Excel date serial value (float),
|
||||
* @param array|DateTimeInterface|float|int|string $endDate Excel date serial value (float),
|
||||
* PHP date timestamp (integer), PHP DateTime object, or a standard date string
|
||||
* @param DateTimeInterface|float|int|string $startDate Excel date serial value (float),
|
||||
* @param array|DateTimeInterface|float|int|string $startDate Excel date serial value (float),
|
||||
* PHP date timestamp (integer), PHP DateTime object, or a standard date string
|
||||
*
|
||||
* @return int|string Number of days between start date and end date or an error
|
||||
* @return array|int|string Number of days between start date and end date or an error
|
||||
*/
|
||||
public static function DAYS($endDate = 0, $startDate = 0)
|
||||
{
|
||||
|
|
@ -331,7 +331,7 @@ class DateTime
|
|||
* PHP DateTime object, or a standard date string
|
||||
* @param mixed $endDate Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
* @param bool $method US or European Method
|
||||
* @param array|bool $method US or European Method
|
||||
* FALSE or omitted: U.S. (NASD) method. If the starting date is
|
||||
* the last day of a month, it becomes equal to the 30th of the
|
||||
* same month. If the ending date is the last day of a month and
|
||||
|
|
@ -343,7 +343,7 @@ class DateTime
|
|||
* occur on the 31st of a month become equal to the 30th of the
|
||||
* same month.
|
||||
*
|
||||
* @return int|string Number of days between start date and end date
|
||||
* @return array|int|string Number of days between start date and end date
|
||||
*/
|
||||
public static function DAYS360($startDate = 0, $endDate = 0, $method = false)
|
||||
{
|
||||
|
|
@ -373,14 +373,14 @@ class DateTime
|
|||
* PHP DateTime object, or a standard date string
|
||||
* @param mixed $endDate Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
* @param int $method Method used for the calculation
|
||||
* @param array|int $method Method used for the calculation
|
||||
* 0 or omitted US (NASD) 30/360
|
||||
* 1 Actual/actual
|
||||
* 2 Actual/360
|
||||
* 3 Actual/365
|
||||
* 4 European 30/360
|
||||
*
|
||||
* @return float|string fraction of the year, or a string containing an error
|
||||
* @return array|float|string fraction of the year, or a string containing an error
|
||||
*/
|
||||
public static function YEARFRAC($startDate = 0, $endDate = 0, $method = 0)
|
||||
{
|
||||
|
|
@ -409,7 +409,7 @@ class DateTime
|
|||
* PHP DateTime object, or a standard date string
|
||||
* @param mixed $dateArgs
|
||||
*
|
||||
* @return int|string Interval between the dates
|
||||
* @return array|int|string Interval between the dates
|
||||
*/
|
||||
public static function NETWORKDAYS($startDate, $endDate, ...$dateArgs)
|
||||
{
|
||||
|
|
@ -464,7 +464,7 @@ class DateTime
|
|||
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
*
|
||||
* @return int|string Day of the month
|
||||
* @return array|int|string Day of the month
|
||||
*/
|
||||
public static function DAYOFMONTH($dateValue = 1)
|
||||
{
|
||||
|
|
@ -492,7 +492,7 @@ class DateTime
|
|||
* 2 Numbers 1 (Monday) through 7 (Sunday).
|
||||
* 3 Numbers 0 (Monday) through 6 (Sunday).
|
||||
*
|
||||
* @return int|string Day of the week value
|
||||
* @return array|int|string Day of the week value
|
||||
*/
|
||||
public static function WEEKDAY($dateValue = 1, $style = 1)
|
||||
{
|
||||
|
|
@ -704,7 +704,7 @@ class DateTime
|
|||
* 17 Week begins on Sunday.
|
||||
* 21 ISO (Jan. 4 is week 1, begins on Monday).
|
||||
*
|
||||
* @return int|string Week Number
|
||||
* @return array|int|string Week Number
|
||||
*/
|
||||
public static function WEEKNUM($dateValue = 1, $method = self::STARTWEEK_SUNDAY)
|
||||
{
|
||||
|
|
@ -727,7 +727,7 @@ class DateTime
|
|||
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
*
|
||||
* @return int|string Week Number
|
||||
* @return array|int|string Week Number
|
||||
*/
|
||||
public static function ISOWEEKNUM($dateValue = 1)
|
||||
{
|
||||
|
|
@ -751,7 +751,7 @@ class DateTime
|
|||
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
*
|
||||
* @return int|string Month of the year
|
||||
* @return array|int|string Month of the year
|
||||
*/
|
||||
public static function MONTHOFYEAR($dateValue = 1)
|
||||
{
|
||||
|
|
@ -775,7 +775,7 @@ class DateTime
|
|||
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
*
|
||||
* @return int|string Year
|
||||
* @return array|int|string Year
|
||||
*/
|
||||
public static function YEAR($dateValue = 1)
|
||||
{
|
||||
|
|
@ -799,7 +799,7 @@ class DateTime
|
|||
* @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard time string
|
||||
*
|
||||
* @return int|string Hour
|
||||
* @return array|int|string Hour
|
||||
*/
|
||||
public static function HOUROFDAY($timeValue = 0)
|
||||
{
|
||||
|
|
@ -823,7 +823,7 @@ class DateTime
|
|||
* @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard time string
|
||||
*
|
||||
* @return int|string Minute
|
||||
* @return array|int|string Minute
|
||||
*/
|
||||
public static function MINUTE($timeValue = 0)
|
||||
{
|
||||
|
|
@ -847,7 +847,7 @@ class DateTime
|
|||
* @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard time string
|
||||
*
|
||||
* @return int|string Second
|
||||
* @return array|int|string Second
|
||||
*/
|
||||
public static function SECOND($timeValue = 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,12 +2,15 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDateHelper;
|
||||
|
||||
class DateParts
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
/**
|
||||
* DAYOFMONTH.
|
||||
*
|
||||
|
|
@ -19,11 +22,18 @@ class DateParts
|
|||
*
|
||||
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
* Or can be an array of date values
|
||||
*
|
||||
* @return int|string Day of the month
|
||||
* @return array|int|string Day of the month
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function day($dateValue)
|
||||
{
|
||||
if (is_array($dateValue)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $dateValue);
|
||||
}
|
||||
|
||||
$weirdResult = self::weirdCondition($dateValue);
|
||||
if ($weirdResult >= 0) {
|
||||
return $weirdResult;
|
||||
|
|
@ -52,11 +62,18 @@ class DateParts
|
|||
*
|
||||
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
* Or can be an array of date values
|
||||
*
|
||||
* @return int|string Month of the year
|
||||
* @return array|int|string Month of the year
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function month($dateValue)
|
||||
{
|
||||
if (is_array($dateValue)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $dateValue);
|
||||
}
|
||||
|
||||
try {
|
||||
$dateValue = Helpers::getDateValue($dateValue);
|
||||
} catch (Exception $e) {
|
||||
|
|
@ -83,11 +100,18 @@ class DateParts
|
|||
*
|
||||
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
* Or can be an array of date values
|
||||
*
|
||||
* @return int|string Year
|
||||
* @return array|int|string Year
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function year($dateValue)
|
||||
{
|
||||
if (is_array($dateValue)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $dateValue);
|
||||
}
|
||||
|
||||
try {
|
||||
$dateValue = Helpers::getDateValue($dateValue);
|
||||
} catch (Exception $e) {
|
||||
|
|
|
|||
|
|
@ -3,11 +3,14 @@
|
|||
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDateHelper;
|
||||
|
||||
class DateValue
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
/**
|
||||
* DATEVALUE.
|
||||
*
|
||||
|
|
@ -21,7 +24,7 @@ class DateValue
|
|||
* Excel Function:
|
||||
* DATEVALUE(dateValue)
|
||||
*
|
||||
* @param string $dateValue Text that represents a date in a Microsoft Excel date format.
|
||||
* @param array|string $dateValue Text that represents a date in a Microsoft Excel date format.
|
||||
* For example, "1/30/2008" or "30-Jan-2008" are text strings within
|
||||
* quotation marks that represent dates. Using the default date
|
||||
* system in Excel for Windows, date_text must represent a date from
|
||||
|
|
@ -29,12 +32,19 @@ class DateValue
|
|||
* system in Excel for the Macintosh, date_text must represent a date
|
||||
* from January 1, 1904, to December 31, 9999. DATEVALUE returns the
|
||||
* #VALUE! error value if date_text is out of this range.
|
||||
* Or can be an array of date values
|
||||
*
|
||||
* @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object,
|
||||
* depending on the value of the ReturnDateType flag
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function fromString($dateValue)
|
||||
{
|
||||
if (is_array($dateValue)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $dateValue);
|
||||
}
|
||||
|
||||
$dti = new DateTimeImmutable();
|
||||
$baseYear = SharedDateHelper::getExcelCalendar();
|
||||
$dateValue = trim(Functions::flattenSingleValue($dateValue ?? ''), '"');
|
||||
|
|
|
|||
|
|
@ -3,12 +3,15 @@
|
|||
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
||||
|
||||
use DateTimeInterface;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDateHelper;
|
||||
|
||||
class Days
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
/**
|
||||
* DAYS.
|
||||
*
|
||||
|
|
@ -17,15 +20,23 @@ class Days
|
|||
* Excel Function:
|
||||
* DAYS(endDate, startDate)
|
||||
*
|
||||
* @param DateTimeInterface|float|int|string $endDate Excel date serial value (float),
|
||||
* PHP date timestamp (integer), PHP DateTime object, or a standard date string
|
||||
* @param DateTimeInterface|float|int|string $startDate Excel date serial value (float),
|
||||
* PHP date timestamp (integer), PHP DateTime object, or a standard date string
|
||||
* @param array|DateTimeInterface|float|int|string $endDate Excel date serial value (float),
|
||||
* PHP date timestamp (integer), PHP DateTime object, or a standard date string
|
||||
* Or can be an array of date values
|
||||
* @param array|DateTimeInterface|float|int|string $startDate Excel date serial value (float),
|
||||
* PHP date timestamp (integer), PHP DateTime object, or a standard date string
|
||||
* Or can be an array of date values
|
||||
*
|
||||
* @return int|string Number of days between start date and end date or an error
|
||||
* @return array|int|string Number of days between start date and end date or an error
|
||||
* If an array of values is passed for the $startDate or $endDays,arguments, then the returned result
|
||||
* will also be an array with matching dimensions
|
||||
*/
|
||||
public static function between($endDate, $startDate)
|
||||
{
|
||||
if (is_array($endDate) || is_array($startDate)) {
|
||||
return self::evaluateArrayArguments([self::class, __FUNCTION__], $endDate, $startDate);
|
||||
}
|
||||
|
||||
try {
|
||||
$startDate = Helpers::getDateValue($startDate);
|
||||
$endDate = Helpers::getDateValue($endDate);
|
||||
|
|
|
|||
|
|
@ -2,12 +2,15 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDateHelper;
|
||||
|
||||
class Days360
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
/**
|
||||
* DAYS360.
|
||||
*
|
||||
|
|
@ -18,11 +21,13 @@ class Days360
|
|||
* Excel Function:
|
||||
* DAYS360(startDate,endDate[,method])
|
||||
*
|
||||
* @param mixed $startDate Excel date serial value (float), PHP date timestamp (integer),
|
||||
* @param array|mixed $startDate Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
* @param mixed $endDate Excel date serial value (float), PHP date timestamp (integer),
|
||||
* Or can be an array of date values
|
||||
* @param array|mixed $endDate Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
* @param mixed $method US or European Method as a bool
|
||||
* Or can be an array of date values
|
||||
* @param array|mixed $method US or European Method as a bool
|
||||
* FALSE or omitted: U.S. (NASD) method. If the starting date is
|
||||
* the last day of a month, it becomes equal to the 30th of the
|
||||
* same month. If the ending date is the last day of a month and
|
||||
|
|
@ -33,11 +38,18 @@ class Days360
|
|||
* TRUE: European method. Starting dates and ending dates that
|
||||
* occur on the 31st of a month become equal to the 30th of the
|
||||
* same month.
|
||||
* Or can be an array of methods
|
||||
*
|
||||
* @return int|string Number of days between start date and end date
|
||||
* @return array|int|string Number of days between start date and end date
|
||||
* If an array of values is passed for the $startDate or $endDays,arguments, then the returned result
|
||||
* will also be an array with matching dimensions
|
||||
*/
|
||||
public static function between($startDate = 0, $endDate = 0, $method = false)
|
||||
{
|
||||
if (is_array($startDate) || is_array($endDate) || is_array($method)) {
|
||||
return self::evaluateArrayArguments([self::class, __FUNCTION__], $startDate, $endDate, $method);
|
||||
}
|
||||
|
||||
try {
|
||||
$startDate = Helpers::getDateValue($startDate);
|
||||
$endDate = Helpers::getDateValue($endDate);
|
||||
|
|
|
|||
|
|
@ -4,25 +4,37 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
|||
|
||||
use DateInterval;
|
||||
use DateTime;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDateHelper;
|
||||
|
||||
class Difference
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
/**
|
||||
* DATEDIF.
|
||||
*
|
||||
* @param mixed $startDate Excel date serial value, PHP date/time stamp, PHP DateTime object
|
||||
* or a standard date string
|
||||
* Or can be an array of date values
|
||||
* @param mixed $endDate Excel date serial value, PHP date/time stamp, PHP DateTime object
|
||||
* or a standard date string
|
||||
* @param string $unit
|
||||
* Or can be an array of date values
|
||||
* @param array|string $unit
|
||||
* Or can be an array of unit values
|
||||
*
|
||||
* @return int|string Interval between the dates
|
||||
* @return array|int|string Interval between the dates
|
||||
* If an array of values is passed for the $startDate or $endDays,arguments, then the returned result
|
||||
* will also be an array with matching dimensions
|
||||
*/
|
||||
public static function interval($startDate, $endDate, $unit = 'D')
|
||||
{
|
||||
if (is_array($startDate) || is_array($endDate) || is_array($unit)) {
|
||||
return self::evaluateArrayArguments([self::class, __FUNCTION__], $startDate, $endDate, $unit);
|
||||
}
|
||||
|
||||
try {
|
||||
$startDate = Helpers::getDateValue($startDate);
|
||||
$endDate = Helpers::getDateValue($endDate);
|
||||
|
|
|
|||
|
|
@ -2,10 +2,13 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
|
||||
class Month
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
/**
|
||||
* EDATE.
|
||||
*
|
||||
|
|
@ -19,15 +22,23 @@ class Month
|
|||
*
|
||||
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
* @param int $adjustmentMonths The number of months before or after start_date.
|
||||
* Or can be an array of date values
|
||||
* @param array|int $adjustmentMonths The number of months before or after start_date.
|
||||
* A positive value for months yields a future date;
|
||||
* a negative value yields a past date.
|
||||
* Or can be an array of adjustment values
|
||||
*
|
||||
* @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object,
|
||||
* @return array|mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object,
|
||||
* depending on the value of the ReturnDateType flag
|
||||
* If an array of values is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function adjust($dateValue, $adjustmentMonths)
|
||||
{
|
||||
if (is_array($dateValue) || is_array($adjustmentMonths)) {
|
||||
return self::evaluateArrayArguments([self::class, __FUNCTION__], $dateValue, $adjustmentMonths);
|
||||
}
|
||||
|
||||
try {
|
||||
$dateValue = Helpers::getDateValue($dateValue, false);
|
||||
$adjustmentMonths = Helpers::validateNumericNull($adjustmentMonths);
|
||||
|
|
@ -54,15 +65,23 @@ class Month
|
|||
*
|
||||
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
* @param int $adjustmentMonths The number of months before or after start_date.
|
||||
* Or can be an array of date values
|
||||
* @param array|int $adjustmentMonths The number of months before or after start_date.
|
||||
* A positive value for months yields a future date;
|
||||
* a negative value yields a past date.
|
||||
* Or can be an array of adjustment values
|
||||
*
|
||||
* @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object,
|
||||
* @return array|mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object,
|
||||
* depending on the value of the ReturnDateType flag
|
||||
* If an array of values is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function lastDay($dateValue, $adjustmentMonths)
|
||||
{
|
||||
if (is_array($dateValue) || is_array($adjustmentMonths)) {
|
||||
return self::evaluateArrayArguments([self::class, __FUNCTION__], $dateValue, $adjustmentMonths);
|
||||
}
|
||||
|
||||
try {
|
||||
$dateValue = Helpers::getDateValue($dateValue, false);
|
||||
$adjustmentMonths = Helpers::validateNumericNull($adjustmentMonths);
|
||||
|
|
|
|||
|
|
@ -2,11 +2,14 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
|
||||
class NetworkDays
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
/**
|
||||
* NETWORKDAYS.
|
||||
*
|
||||
|
|
@ -20,14 +23,26 @@ class NetworkDays
|
|||
*
|
||||
* @param mixed $startDate Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
* Or can be an array of date values
|
||||
* @param mixed $endDate Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
* @param mixed $dateArgs
|
||||
* Or can be an array of date values
|
||||
* @param mixed $dateArgs An array of dates (such as holidays) to exclude from the calculation
|
||||
*
|
||||
* @return int|string Interval between the dates
|
||||
* @return array|int|string Interval between the dates
|
||||
*/
|
||||
public static function count($startDate, $endDate, ...$dateArgs)
|
||||
{
|
||||
if (is_array($startDate) || is_array($endDate)) {
|
||||
return self::evaluateArrayArgumentsSubset(
|
||||
[self::class, __FUNCTION__],
|
||||
2,
|
||||
$startDate,
|
||||
$endDate,
|
||||
...$dateArgs
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
// Retrieve the mandatory start and end date that are referenced in the function definition
|
||||
$sDate = Helpers::getDateValue($startDate);
|
||||
|
|
|
|||
|
|
@ -3,12 +3,15 @@
|
|||
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
||||
|
||||
use DateTime;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDateHelper;
|
||||
|
||||
class Time
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
/**
|
||||
* TIME.
|
||||
*
|
||||
|
|
@ -20,23 +23,31 @@ class Time
|
|||
* Excel Function:
|
||||
* TIME(hour,minute,second)
|
||||
*
|
||||
* @param mixed $hour A number from 0 (zero) to 32767 representing the hour.
|
||||
* @param array|int $hour A number from 0 (zero) to 32767 representing the hour.
|
||||
* Any value greater than 23 will be divided by 24 and the remainder
|
||||
* will be treated as the hour value. For example, TIME(27,0,0) =
|
||||
* TIME(3,0,0) = .125 or 3:00 AM.
|
||||
* @param mixed $minute A number from 0 to 32767 representing the minute.
|
||||
* @param array|int $minute A number from 0 to 32767 representing the minute.
|
||||
* Any value greater than 59 will be converted to hours and minutes.
|
||||
* For example, TIME(0,750,0) = TIME(12,30,0) = .520833 or 12:30 PM.
|
||||
* @param mixed $second A number from 0 to 32767 representing the second.
|
||||
* @param array|int $second A number from 0 to 32767 representing the second.
|
||||
* Any value greater than 59 will be converted to hours, minutes,
|
||||
* and seconds. For example, TIME(0,0,2000) = TIME(0,33,22) = .023148
|
||||
* or 12:33:20 AM
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*
|
||||
* @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object,
|
||||
* @return array|mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object,
|
||||
* depending on the value of the ReturnDateType flag
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function fromHMS($hour, $minute, $second)
|
||||
{
|
||||
if (is_array($hour) || is_array($minute) || is_array($second)) {
|
||||
return self::evaluateArrayArguments([self::class, __FUNCTION__], $hour, $minute, $second);
|
||||
}
|
||||
|
||||
try {
|
||||
$hour = self::toIntWithNullBool($hour);
|
||||
$minute = self::toIntWithNullBool($minute);
|
||||
|
|
|
|||
|
|
@ -2,12 +2,15 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDateHelper;
|
||||
|
||||
class TimeParts
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
/**
|
||||
* HOUROFDAY.
|
||||
*
|
||||
|
|
@ -19,11 +22,18 @@ class TimeParts
|
|||
*
|
||||
* @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard time string
|
||||
* Or can be an array of date/time values
|
||||
*
|
||||
* @return int|string Hour
|
||||
* @return array|int|string Hour
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function hour($timeValue)
|
||||
{
|
||||
if (is_array($timeValue)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $timeValue);
|
||||
}
|
||||
|
||||
try {
|
||||
$timeValue = Functions::flattenSingleValue($timeValue);
|
||||
Helpers::nullFalseTrueToNumber($timeValue);
|
||||
|
|
@ -53,11 +63,18 @@ class TimeParts
|
|||
*
|
||||
* @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard time string
|
||||
* Or can be an array of date/time values
|
||||
*
|
||||
* @return int|string Minute
|
||||
* @return array|int|string Minute
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function minute($timeValue)
|
||||
{
|
||||
if (is_array($timeValue)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $timeValue);
|
||||
}
|
||||
|
||||
try {
|
||||
$timeValue = Functions::flattenSingleValue($timeValue);
|
||||
Helpers::nullFalseTrueToNumber($timeValue);
|
||||
|
|
@ -87,11 +104,18 @@ class TimeParts
|
|||
*
|
||||
* @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard time string
|
||||
* Or can be an array of date/time values
|
||||
*
|
||||
* @return int|string Second
|
||||
* @return array|int|string Second
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function second($timeValue)
|
||||
{
|
||||
if (is_array($timeValue)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $timeValue);
|
||||
}
|
||||
|
||||
try {
|
||||
$timeValue = Functions::flattenSingleValue($timeValue);
|
||||
Helpers::nullFalseTrueToNumber($timeValue);
|
||||
|
|
|
|||
|
|
@ -3,11 +3,14 @@
|
|||
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
||||
|
||||
use Datetime;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDateHelper;
|
||||
|
||||
class TimeValue
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
/**
|
||||
* TIMEVALUE.
|
||||
*
|
||||
|
|
@ -21,16 +24,23 @@ class TimeValue
|
|||
* Excel Function:
|
||||
* TIMEVALUE(timeValue)
|
||||
*
|
||||
* @param string $timeValue A text string that represents a time in any one of the Microsoft
|
||||
* @param array|string $timeValue A text string that represents a time in any one of the Microsoft
|
||||
* Excel time formats; for example, "6:45 PM" and "18:45" text strings
|
||||
* within quotation marks that represent time.
|
||||
* Date information in time_text is ignored.
|
||||
* Or can be an array of date/time values
|
||||
*
|
||||
* @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object,
|
||||
* depending on the value of the ReturnDateType flag
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function fromString($timeValue)
|
||||
{
|
||||
if (is_array($timeValue)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $timeValue);
|
||||
}
|
||||
|
||||
$timeValue = trim(Functions::flattenSingleValue($timeValue ?? ''), '"');
|
||||
$timeValue = str_replace(['/', '.'], '-', $timeValue);
|
||||
|
||||
|
|
|
|||
|
|
@ -3,12 +3,15 @@
|
|||
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
||||
|
||||
use DateTime;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDateHelper;
|
||||
|
||||
class Week
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
/**
|
||||
* WEEKNUM.
|
||||
*
|
||||
|
|
@ -24,7 +27,8 @@ class Week
|
|||
*
|
||||
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
* @param int $method Week begins on Sunday or Monday
|
||||
* Or can be an array of date values
|
||||
* @param array|int $method Week begins on Sunday or Monday
|
||||
* 1 or omitted Week begins on Sunday.
|
||||
* 2 Week begins on Monday.
|
||||
* 11 Week begins on Monday.
|
||||
|
|
@ -35,11 +39,18 @@ class Week
|
|||
* 16 Week begins on Saturday.
|
||||
* 17 Week begins on Sunday.
|
||||
* 21 ISO (Jan. 4 is week 1, begins on Monday).
|
||||
* Or can be an array of methods
|
||||
*
|
||||
* @return int|string Week Number
|
||||
* @return array|int|string Week Number
|
||||
* If an array of values is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function number($dateValue, $method = Constants::STARTWEEK_SUNDAY)
|
||||
{
|
||||
if (is_array($dateValue) || is_array($method)) {
|
||||
return self::evaluateArrayArguments([self::class, __FUNCTION__], $dateValue, $method);
|
||||
}
|
||||
|
||||
$origDateValueNull = empty($dateValue);
|
||||
|
||||
try {
|
||||
|
|
@ -88,11 +99,18 @@ class Week
|
|||
*
|
||||
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
* Or can be an array of date values
|
||||
*
|
||||
* @return int|string Week Number
|
||||
* @return array|int|string Week Number
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function isoWeekNumber($dateValue)
|
||||
{
|
||||
if (is_array($dateValue)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $dateValue);
|
||||
}
|
||||
|
||||
if (self::apparentBug($dateValue)) {
|
||||
return 52;
|
||||
}
|
||||
|
|
@ -119,17 +137,25 @@ class Week
|
|||
* Excel Function:
|
||||
* WEEKDAY(dateValue[,style])
|
||||
*
|
||||
* @param null|float|int|string $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* @param null|array|float|int|string $dateValue Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
* Or can be an array of date values
|
||||
* @param mixed $style A number that determines the type of return value
|
||||
* 1 or omitted Numbers 1 (Sunday) through 7 (Saturday).
|
||||
* 2 Numbers 1 (Monday) through 7 (Sunday).
|
||||
* 3 Numbers 0 (Monday) through 6 (Sunday).
|
||||
* Or can be an array of styles
|
||||
*
|
||||
* @return int|string Day of the week value
|
||||
* @return array|int|string Day of the week value
|
||||
* If an array of values is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function day($dateValue, $style = 1)
|
||||
{
|
||||
if (is_array($dateValue) || is_array($style)) {
|
||||
return self::evaluateArrayArguments([self::class, __FUNCTION__], $dateValue, $style);
|
||||
}
|
||||
|
||||
try {
|
||||
$dateValue = Helpers::getDateValue($dateValue);
|
||||
$style = self::validateStyle($style);
|
||||
|
|
|
|||
|
|
@ -2,11 +2,14 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
|
||||
class WorkDay
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
/**
|
||||
* WORKDAY.
|
||||
*
|
||||
|
|
@ -18,27 +21,37 @@ class WorkDay
|
|||
* Excel Function:
|
||||
* WORKDAY(startDate,endDays[,holidays[,holiday[,...]]])
|
||||
*
|
||||
* @param mixed $startDate Excel date serial value (float), PHP date timestamp (integer),
|
||||
* @param array|mixed $startDate Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
* @param int $endDays The number of nonweekend and nonholiday days before or after
|
||||
* Or can be an array of date values
|
||||
* @param array|int $endDays The number of nonweekend and nonholiday days before or after
|
||||
* startDate. A positive value for days yields a future date; a
|
||||
* negative value yields a past date.
|
||||
* @param mixed $dateArgs
|
||||
* Or can be an array of int values
|
||||
* @param null|mixed $dateArgs An array of dates (such as holidays) to exclude from the calculation
|
||||
*
|
||||
* @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object,
|
||||
* @return array|mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object,
|
||||
* depending on the value of the ReturnDateType flag
|
||||
* If an array of values is passed for the $startDate or $endDays,arguments, then the returned result
|
||||
* will also be an array with matching dimensions
|
||||
*/
|
||||
public static function date($startDate, $endDays, ...$dateArgs)
|
||||
{
|
||||
if (is_array($startDate) || is_array($endDays)) {
|
||||
return self::evaluateArrayArgumentsSubset(
|
||||
[self::class, __FUNCTION__],
|
||||
2,
|
||||
$startDate,
|
||||
$endDays,
|
||||
...$dateArgs
|
||||
);
|
||||
}
|
||||
|
||||
// Retrieve the mandatory start date and days that are referenced in the function definition
|
||||
try {
|
||||
$startDate = Helpers::getDateValue($startDate);
|
||||
$endDays = Helpers::validateNumericNull($endDays);
|
||||
$dateArgs = Functions::flattenArray($dateArgs);
|
||||
$holidayArray = [];
|
||||
foreach ($dateArgs as $holidayDate) {
|
||||
$holidayArray[] = Helpers::getDateValue($holidayDate);
|
||||
}
|
||||
$holidayArray = array_map([Helpers::class, 'getDateValue'], Functions::flattenArray($dateArgs));
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
|
@ -64,9 +77,8 @@ class WorkDay
|
|||
private static function incrementing(float $startDate, int $endDays, array $holidayArray)
|
||||
{
|
||||
// Adjust the start date if it falls over a weekend
|
||||
|
||||
$startDoW = self::getWeekDay($startDate, 3);
|
||||
if (self::getWeekDay($startDate, 3) >= 5) {
|
||||
if ($startDoW >= 5) {
|
||||
$startDate += 7 - $startDoW;
|
||||
--$endDays;
|
||||
}
|
||||
|
|
@ -126,9 +138,8 @@ class WorkDay
|
|||
private static function decrementing(float $startDate, int $endDays, array $holidayArray)
|
||||
{
|
||||
// Adjust the start date if it falls over a weekend
|
||||
|
||||
$startDoW = self::getWeekDay($startDate, 3);
|
||||
if (self::getWeekDay($startDate, 3) >= 5) {
|
||||
if ($startDoW >= 5) {
|
||||
$startDate += -$startDoW + 4;
|
||||
++$endDays;
|
||||
}
|
||||
|
|
@ -172,6 +183,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;
|
||||
}
|
||||
|
|
@ -182,8 +194,8 @@ class WorkDay
|
|||
|
||||
private static function getWeekDay(float $date, int $wd): int
|
||||
{
|
||||
$result = Week::day($date, $wd);
|
||||
$result = Functions::scalar(Week::day($date, $wd));
|
||||
|
||||
return is_string($result) ? -1 : $result;
|
||||
return is_int($result) ? $result : -1;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,12 +2,15 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDateHelper;
|
||||
|
||||
class YearFrac
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
/**
|
||||
* YEARFRAC.
|
||||
*
|
||||
|
|
@ -23,19 +26,28 @@ class YearFrac
|
|||
*
|
||||
* @param mixed $startDate Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
* Or can be an array of methods
|
||||
* @param mixed $endDate Excel date serial value (float), PHP date timestamp (integer),
|
||||
* PHP DateTime object, or a standard date string
|
||||
* @param int $method Method used for the calculation
|
||||
* Or can be an array of methods
|
||||
* @param array|int $method Method used for the calculation
|
||||
* 0 or omitted US (NASD) 30/360
|
||||
* 1 Actual/actual
|
||||
* 2 Actual/360
|
||||
* 3 Actual/365
|
||||
* 4 European 30/360
|
||||
* Or can be an array of methods
|
||||
*
|
||||
* @return float|string fraction of the year, or a string containing an error
|
||||
* @return array|float|string fraction of the year, or a string containing an error
|
||||
* If an array of values is passed for the $startDate or $endDays,arguments, then the returned result
|
||||
* will also be an array with matching dimensions
|
||||
*/
|
||||
public static function fraction($startDate, $endDate, $method = 0)
|
||||
{
|
||||
if (is_array($startDate) || is_array($endDate) || is_array($method)) {
|
||||
return self::evaluateArrayArguments([self::class, __FUNCTION__], $startDate, $endDate, $method);
|
||||
}
|
||||
|
||||
try {
|
||||
$method = (int) Helpers::validateNumericNull($method);
|
||||
$sDate = Helpers::getDateValue($startDate);
|
||||
|
|
@ -50,15 +62,15 @@ class YearFrac
|
|||
|
||||
switch ($method) {
|
||||
case 0:
|
||||
return Days360::between($startDate, $endDate) / 360;
|
||||
return Functions::scalar(Days360::between($startDate, $endDate)) / 360;
|
||||
case 1:
|
||||
return self::method1($startDate, $endDate);
|
||||
case 2:
|
||||
return Difference::interval($startDate, $endDate) / 360;
|
||||
return Functions::scalar(Difference::interval($startDate, $endDate)) / 360;
|
||||
case 3:
|
||||
return Difference::interval($startDate, $endDate) / 365;
|
||||
return Functions::scalar(Difference::interval($startDate, $endDate)) / 365;
|
||||
case 4:
|
||||
return Days360::between($startDate, $endDate, true) / 360;
|
||||
return Functions::scalar(Days360::between($startDate, $endDate, true)) / 360;
|
||||
}
|
||||
|
||||
return Functions::NAN();
|
||||
|
|
@ -87,7 +99,7 @@ class YearFrac
|
|||
|
||||
private static function method1(float $startDate, float $endDate): float
|
||||
{
|
||||
$days = Difference::interval($startDate, $endDate);
|
||||
$days = Functions::scalar(Difference::interval($startDate, $endDate));
|
||||
$startYear = (int) DateParts::year($startDate);
|
||||
$endYear = (int) DateParts::year($endDate);
|
||||
$years = $endYear - $startYear + 1;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,174 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\Engine;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
|
||||
class ArrayArgumentProcessor
|
||||
{
|
||||
/**
|
||||
* @var ArrayArgumentHelper
|
||||
*/
|
||||
private static $arrayArgumentHelper;
|
||||
|
||||
/**
|
||||
* @param mixed ...$arguments
|
||||
*/
|
||||
public static function processArguments(
|
||||
ArrayArgumentHelper $arrayArgumentHelper,
|
||||
callable $method,
|
||||
...$arguments
|
||||
): array {
|
||||
self::$arrayArgumentHelper = $arrayArgumentHelper;
|
||||
|
||||
if (self::$arrayArgumentHelper->hasArrayArgument() === false) {
|
||||
return [$method(...$arguments)];
|
||||
}
|
||||
|
||||
if (self::$arrayArgumentHelper->arrayArguments() === 1) {
|
||||
$nthArgument = self::$arrayArgumentHelper->getFirstArrayArgumentNumber();
|
||||
|
||||
return self::evaluateNthArgumentAsArray($method, $nthArgument, ...$arguments);
|
||||
}
|
||||
|
||||
$singleRowVectorIndex = self::$arrayArgumentHelper->getSingleRowVector();
|
||||
$singleColumnVectorIndex = self::$arrayArgumentHelper->getSingleColumnVector();
|
||||
if ($singleRowVectorIndex !== null && $singleColumnVectorIndex !== null) {
|
||||
// Basic logic for a single row vector and a single column vector
|
||||
return self::evaluateVectorPair($method, $singleRowVectorIndex, $singleColumnVectorIndex, ...$arguments);
|
||||
}
|
||||
|
||||
$matrixPair = self::$arrayArgumentHelper->getMatrixPair();
|
||||
if ($matrixPair !== []) {
|
||||
if (
|
||||
(self::$arrayArgumentHelper->isVector($matrixPair[0]) === true &&
|
||||
self::$arrayArgumentHelper->isVector($matrixPair[1]) === false) ||
|
||||
(self::$arrayArgumentHelper->isVector($matrixPair[0]) === false &&
|
||||
self::$arrayArgumentHelper->isVector($matrixPair[1]) === true)
|
||||
) {
|
||||
// Logic for a matrix and a vector (row or column)
|
||||
return self::evaluateVectorMatrixPair($method, $matrixPair, ...$arguments);
|
||||
}
|
||||
// Logic for matrix/matrix, column vector/column vector or row vector/row vector
|
||||
return self::evaluateMatrixPair($method, $matrixPair, ...$arguments);
|
||||
}
|
||||
|
||||
// Still need to work out the logic for more than two array arguments,
|
||||
// For the moment, we're throwing an Exception when we initialise the ArrayArgumentHelper
|
||||
return ['#VALUE!'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed ...$arguments
|
||||
*/
|
||||
private static function evaluateVectorMatrixPair(callable $method, array $matrixIndexes, ...$arguments): array
|
||||
{
|
||||
$matrix2 = array_pop($matrixIndexes);
|
||||
/** @var array $matrixValues2 */
|
||||
$matrixValues2 = $arguments[$matrix2];
|
||||
$matrix1 = array_pop($matrixIndexes);
|
||||
/** @var array $matrixValues1 */
|
||||
$matrixValues1 = $arguments[$matrix1];
|
||||
|
||||
$rows = min(array_map([self::$arrayArgumentHelper, 'rowCount'], [$matrix1, $matrix2]));
|
||||
$columns = min(array_map([self::$arrayArgumentHelper, 'columnCount'], [$matrix1, $matrix2]));
|
||||
|
||||
if ($rows === 1) {
|
||||
$rows = max(array_map([self::$arrayArgumentHelper, 'rowCount'], [$matrix1, $matrix2]));
|
||||
}
|
||||
if ($columns === 1) {
|
||||
$columns = max(array_map([self::$arrayArgumentHelper, 'columnCount'], [$matrix1, $matrix2]));
|
||||
}
|
||||
|
||||
$result = [];
|
||||
for ($rowIndex = 0; $rowIndex < $rows; ++$rowIndex) {
|
||||
for ($columnIndex = 0; $columnIndex < $columns; ++$columnIndex) {
|
||||
$rowIndex1 = self::$arrayArgumentHelper->isRowVector($matrix1) ? 0 : $rowIndex;
|
||||
$columnIndex1 = self::$arrayArgumentHelper->isColumnVector($matrix1) ? 0 : $columnIndex;
|
||||
$value1 = $matrixValues1[$rowIndex1][$columnIndex1];
|
||||
$rowIndex2 = self::$arrayArgumentHelper->isRowVector($matrix2) ? 0 : $rowIndex;
|
||||
$columnIndex2 = self::$arrayArgumentHelper->isColumnVector($matrix2) ? 0 : $columnIndex;
|
||||
$value2 = $matrixValues2[$rowIndex2][$columnIndex2];
|
||||
$arguments[$matrix1] = $value1;
|
||||
$arguments[$matrix2] = $value2;
|
||||
|
||||
$result[$rowIndex][$columnIndex] = $method(...$arguments);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed ...$arguments
|
||||
*/
|
||||
private static function evaluateMatrixPair(callable $method, array $matrixIndexes, ...$arguments): array
|
||||
{
|
||||
$matrix2 = array_pop($matrixIndexes);
|
||||
/** @var array $matrixValues2 */
|
||||
$matrixValues2 = $arguments[$matrix2];
|
||||
$matrix1 = array_pop($matrixIndexes);
|
||||
/** @var array $matrixValues1 */
|
||||
$matrixValues1 = $arguments[$matrix1];
|
||||
|
||||
$result = [];
|
||||
foreach ($matrixValues1 as $rowIndex => $row) {
|
||||
foreach ($row as $columnIndex => $value1) {
|
||||
if (isset($matrixValues2[$rowIndex][$columnIndex]) === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$value2 = $matrixValues2[$rowIndex][$columnIndex];
|
||||
$arguments[$matrix1] = $value1;
|
||||
$arguments[$matrix2] = $value2;
|
||||
|
||||
$result[$rowIndex][$columnIndex] = $method(...$arguments);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed ...$arguments
|
||||
*/
|
||||
private static function evaluateVectorPair(callable $method, int $rowIndex, int $columnIndex, ...$arguments): array
|
||||
{
|
||||
$rowVector = Functions::flattenArray($arguments[$rowIndex]);
|
||||
$columnVector = Functions::flattenArray($arguments[$columnIndex]);
|
||||
|
||||
$result = [];
|
||||
foreach ($columnVector as $column) {
|
||||
$rowResults = [];
|
||||
foreach ($rowVector as $row) {
|
||||
$arguments[$rowIndex] = $row;
|
||||
$arguments[$columnIndex] = $column;
|
||||
|
||||
$rowResults[] = $method(...$arguments);
|
||||
}
|
||||
$result[] = $rowResults;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note, offset is from 1 (for the first argument) rather than from 0.
|
||||
*
|
||||
* @param mixed ...$arguments
|
||||
*/
|
||||
private static function evaluateNthArgumentAsArray(callable $method, int $nthArgument, ...$arguments): array
|
||||
{
|
||||
$values = array_slice($arguments, $nthArgument - 1, 1);
|
||||
/** @var array $values */
|
||||
$values = array_pop($values);
|
||||
|
||||
$result = [];
|
||||
foreach ($values as $value) {
|
||||
$arguments[$nthArgument - 1] = $value;
|
||||
$result[] = $method(...$arguments);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
|
@ -608,6 +608,24 @@ class Functions
|
|||
return $arrayValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return null|mixed
|
||||
*/
|
||||
public static function scalar($value)
|
||||
{
|
||||
if (!is_array($value)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
do {
|
||||
$value = array_pop($value);
|
||||
} while (is_array($value));
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a multi-dimensional array to a simple 1-dimensional array, but retain an element of indexing.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||
|
||||
class DateDifTest extends AllSetupTeardown
|
||||
{
|
||||
/**
|
||||
|
|
@ -22,4 +24,30 @@ class DateDifTest extends AllSetupTeardown
|
|||
{
|
||||
return require 'tests/data/Calculation/DateTime/DATEDIF.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerDateDifArray
|
||||
*/
|
||||
public function testDateDifArray(array $expectedResult, string $startDate, string $endDate, ?string $methods): void
|
||||
{
|
||||
$calculation = Calculation::getInstance();
|
||||
|
||||
if ($methods === null) {
|
||||
$formula = "=DATEDIF({$startDate}, {$endDate})";
|
||||
} else {
|
||||
$formula = "=DATEDIF({$startDate}, {$endDate}, {$methods})";
|
||||
}
|
||||
$result = $calculation->_calculateFormulaValue($formula);
|
||||
self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14);
|
||||
}
|
||||
|
||||
public function providerDateDifArray(): array
|
||||
{
|
||||
return [
|
||||
'row vector #1' => [[[364, 202, '#NUM!']], '{"2022-01-01", "2022-06-12", "2023-07-22"}', '"2022-12-31"', null],
|
||||
'column vector #1' => [[[364], [362], [359]], '{"2022-01-01"; "2022-01-03"; "2022-01-06"}', '"2022-12-31"', null],
|
||||
'matrix #1' => [[[365, 266], [139, 1]], '{"2022-01-01", "2022-04-10"; "2022-08-15", "2022-12-31"}', '"2023-01-01"', null],
|
||||
'column vector with methods' => [[[364, 11], [242, 7], [173, 5]], '{"2022-01-01"; "2022-05-03"; "2022-07-11"}', '"2022-12-31"', '{"D", "M"}'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
|
|||
|
||||
use DateTimeImmutable;
|
||||
use DateTimeInterface;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\DateValue;
|
||||
|
||||
class DateValueTest extends AllSetupTeardown
|
||||
|
|
@ -72,4 +73,25 @@ class DateValueTest extends AllSetupTeardown
|
|||
self::assertEquals('#VALUE!', DateValue::fromString('1903-12-31'));
|
||||
self::assertEquals('#VALUE!', DateValue::fromString('1900-02-29'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerDateValueArray
|
||||
*/
|
||||
public function testDateValueArray(array $expectedResult, string $array): void
|
||||
{
|
||||
$calculation = Calculation::getInstance();
|
||||
|
||||
$formula = "=DATEVALUE({$array})";
|
||||
$result = $calculation->_calculateFormulaValue($formula);
|
||||
self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14);
|
||||
}
|
||||
|
||||
public function providerDateValueArray(): array
|
||||
{
|
||||
return [
|
||||
'row vector' => [[[44562, 44724, 45129]], '{"2022-01-01", "2022-06-12", "2023-07-22"}'],
|
||||
'column vector' => [[[44562], [44564], [44567]], '{"2022-01-01"; "2022-01-03"; "2022-01-06"}'],
|
||||
'matrix' => [[[44562, 44571], [44788, 44926]], '{"2022-01-01", "2022-01-10"; "2022-08-15", "2022-12-31"}'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||
|
||||
class DayTest extends AllSetupTeardown
|
||||
{
|
||||
/**
|
||||
|
|
@ -41,4 +43,25 @@ class DayTest extends AllSetupTeardown
|
|||
{
|
||||
return require 'tests/data/Calculation/DateTime/DAYOpenOffice.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerDayArray
|
||||
*/
|
||||
public function testDayArray(array $expectedResult, string $array): void
|
||||
{
|
||||
$calculation = Calculation::getInstance();
|
||||
|
||||
$formula = "=DAY({$array})";
|
||||
$result = $calculation->_calculateFormulaValue($formula);
|
||||
self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14);
|
||||
}
|
||||
|
||||
public function providerDayArray(): array
|
||||
{
|
||||
return [
|
||||
'row vector' => [[[1, 12, 22]], '{"2022-01-01", "2022-06-12", "2023-07-22"}'],
|
||||
'column vector' => [[[1], [3], [6]], '{"2022-01-01"; "2022-01-03"; "2022-01-06"}'],
|
||||
'matrix' => [[[1, 10], [15, 31]], '{"2022-01-01", "2022-01-10"; "2022-08-15", "2022-12-31"}'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||
|
||||
class Days360Test extends AllSetupTeardown
|
||||
{
|
||||
/**
|
||||
|
|
@ -23,4 +25,30 @@ class Days360Test extends AllSetupTeardown
|
|||
{
|
||||
return require 'tests/data/Calculation/DateTime/DAYS360.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerDays360Array
|
||||
*/
|
||||
public function testDays360Array(array $expectedResult, string $startDate, string $endDate, ?string $methods): void
|
||||
{
|
||||
$calculation = Calculation::getInstance();
|
||||
|
||||
if ($methods === null) {
|
||||
$formula = "=DAYS360({$startDate}, {$endDate})";
|
||||
} else {
|
||||
$formula = "=DAYS360({$startDate}, {$endDate}, {$methods})";
|
||||
}
|
||||
$result = $calculation->_calculateFormulaValue($formula);
|
||||
self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14);
|
||||
}
|
||||
|
||||
public function providerDays360Array(): array
|
||||
{
|
||||
return [
|
||||
'row vector #1' => [[[360, 199, -201]], '{"2022-01-01", "2022-06-12", "2023-07-22"}', '"2022-12-31"', null],
|
||||
'column vector #1' => [[[360], [358], [355]], '{"2022-01-01"; "2022-01-03"; "2022-01-06"}', '"2022-12-31"', null],
|
||||
'matrix #1' => [[[0, -9], [-224, -360]], '{"2022-01-01", "2022-01-10"; "2022-08-15", "2022-12-31"}', '"2021-12-31"', null],
|
||||
'column vector with methods' => [[[360, 359], [358, 357], [355, 354]], '{"2022-01-01"; "2022-01-03"; "2022-01-06"}', '"2022-12-31"', '{FALSE, TRUE}'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
|
|||
use DateTime;
|
||||
use DateTimeImmutable;
|
||||
use Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Days;
|
||||
|
||||
class DaysTest extends AllSetupTeardown
|
||||
|
|
@ -42,4 +43,25 @@ class DaysTest extends AllSetupTeardown
|
|||
$obj2 = new DateTimeImmutable('2000-2-29');
|
||||
self::assertSame('#VALUE!', Days::between($obj1, $obj2));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerDaysArray
|
||||
*/
|
||||
public function testDaysArray(array $expectedResult, string $startDate, string $endDate): void
|
||||
{
|
||||
$calculation = Calculation::getInstance();
|
||||
|
||||
$formula = "=DAYS({$startDate}, {$endDate})";
|
||||
$result = $calculation->_calculateFormulaValue($formula);
|
||||
self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14);
|
||||
}
|
||||
|
||||
public function providerDaysArray(): array
|
||||
{
|
||||
return [
|
||||
'row vector #1' => [[[-364, -202, 203]], '{"2022-01-01", "2022-06-12", "2023-07-22"}', '"2022-12-31"'],
|
||||
'column vector #1' => [[[-364], [-362], [-359]], '{"2022-01-01"; "2022-01-03"; "2022-01-06"}', '"2022-12-31"'],
|
||||
'matrix #1' => [[[1, 10], [227, 365]], '{"2022-01-01", "2022-01-10"; "2022-08-15", "2022-12-31"}', '"2021-12-31"'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Month;
|
||||
|
||||
class EDateTest extends AllSetupTeardown
|
||||
|
|
@ -46,4 +47,28 @@ class EDateTest extends AllSetupTeardown
|
|||
// ... with the correct value
|
||||
self::assertEquals($result->format('d-M-Y'), '26-Dec-2011');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerEDateArray
|
||||
*/
|
||||
public function testEDateArray(array $expectedResult, string $dateValues, string $methods): void
|
||||
{
|
||||
$calculation = Calculation::getInstance();
|
||||
|
||||
$formula = "=EDATE({$dateValues}, {$methods})";
|
||||
$result = $calculation->_calculateFormulaValue($formula);
|
||||
self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14);
|
||||
}
|
||||
|
||||
public function providerEDateArray(): array
|
||||
{
|
||||
return [
|
||||
'row vector #1' => [[[44593, 44632, 45337]], '{"2022-01-01", "2022-02-12", "2024-01-15"}', '1'],
|
||||
'column vector #1' => [[[44593], [44632], [45337]], '{"2022-01-01"; "2022-02-12"; "2024-01-15"}', '1'],
|
||||
'matrix #1' => [[[44593, 44632], [44652, 45343]], '{"2022-01-01", "2022-02-12"; "2022-03-01", "2024-01-21"}', '1'],
|
||||
'row vector #2' => [[[44573, 44604, 44632]], '"2022-02-12"', '{-1, 0, 1}'],
|
||||
'column vector #2' => [[[44573], [44604], [44632]], '"2022-02-12"', '{-1; 0; 1}'],
|
||||
'matrix #2' => [[[44573, 44604], [44632, 45334]], '"2022-02-12"', '{-1, 0; 1, 24}'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Month;
|
||||
|
||||
class EoMonthTest extends AllSetupTeardown
|
||||
|
|
@ -45,4 +46,28 @@ class EoMonthTest extends AllSetupTeardown
|
|||
// ... with the correct value
|
||||
self::assertSame($result->format('d-M-Y'), '31-Dec-2011');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerEoMonthArray
|
||||
*/
|
||||
public function testEoMonthArray(array $expectedResult, string $dateValues, string $methods): void
|
||||
{
|
||||
$calculation = Calculation::getInstance();
|
||||
|
||||
$formula = "=EOMONTH({$dateValues}, {$methods})";
|
||||
$result = $calculation->_calculateFormulaValue($formula);
|
||||
self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14);
|
||||
}
|
||||
|
||||
public function providerEoMonthArray(): array
|
||||
{
|
||||
return [
|
||||
'row vector #1' => [[[44620, 44651, 45351]], '{"2022-01-01", "2022-02-12", "2024-01-15"}', '1'],
|
||||
'column vector #1' => [[[44620], [44651], [45351]], '{"2022-01-01"; "2022-02-12"; "2024-01-15"}', '1'],
|
||||
'matrix #1' => [[[44620, 44651], [44681, 45351]], '{"2022-01-01", "2022-02-12"; "2022-03-01", "2024-01-21"}', '1'],
|
||||
'row vector #2' => [[[44592, 44620, 44651]], '"2022-02-12"', '{-1, 0, 1}'],
|
||||
'column vector #2' => [[[44592], [44620], [44651]], '"2022-02-12"', '{-1; 0; 1}'],
|
||||
'matrix #2' => [[[44592, 44620], [44651, 45351]], '"2022-02-12"', '{-1, 0; 1, 24}'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||
|
||||
class HourTest extends AllSetupTeardown
|
||||
{
|
||||
/**
|
||||
|
|
@ -22,4 +24,25 @@ class HourTest extends AllSetupTeardown
|
|||
{
|
||||
return require 'tests/data/Calculation/DateTime/HOUR.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerHourArray
|
||||
*/
|
||||
public function testHourArray(array $expectedResult, string $array): void
|
||||
{
|
||||
$calculation = Calculation::getInstance();
|
||||
|
||||
$formula = "=HOUR({$array})";
|
||||
$result = $calculation->_calculateFormulaValue($formula);
|
||||
self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14);
|
||||
}
|
||||
|
||||
public function providerHourArray(): array
|
||||
{
|
||||
return [
|
||||
'row vector' => [[[1, 13, 19]], '{"2022-02-09 01:02:03", "2022-02-09 13:14:15", "2022-02-09 19:20:21"}'],
|
||||
'column vector' => [[[1], [13], [19]], '{"2022-02-09 01:02:03"; "2022-02-09 13:14:15"; "2022-02-09 19:20:21"}'],
|
||||
'matrix' => [[[1, 13], [19, 23]], '{"2022-02-09 01:02:03", "2022-02-09 13:14:15"; "2022-02-09 19:20:21", "1999-12-31 23:59:59"}'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||
|
||||
class IsoWeekNumTest extends AllSetupTeardown
|
||||
{
|
||||
/**
|
||||
|
|
@ -44,4 +46,25 @@ class IsoWeekNumTest extends AllSetupTeardown
|
|||
{
|
||||
return require 'tests/data/Calculation/DateTime/ISOWEEKNUM1904.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerIsoWeekNumArray
|
||||
*/
|
||||
public function testIsoWeekNumArray(array $expectedResult, string $array): void
|
||||
{
|
||||
$calculation = Calculation::getInstance();
|
||||
|
||||
$formula = "=ISOWEEKNUM({$array})";
|
||||
$result = $calculation->_calculateFormulaValue($formula);
|
||||
self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14);
|
||||
}
|
||||
|
||||
public function providerIsoWeekNumArray(): array
|
||||
{
|
||||
return [
|
||||
'row vector' => [[[52, 23, 29]], '{"2022-01-01", "2022-06-12", "2023-07-22"}'],
|
||||
'column vector' => [[[52], [13], [26]], '{"2023-01-01"; "2023-04-01"; "2023-07-01"}'],
|
||||
'matrix' => [[[53, 52], [52, 52]], '{"2021-01-01", "2021-12-31"; "2023-01-01", "2023-12-31"}'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||
|
||||
class MinuteTest extends AllSetupTeardown
|
||||
{
|
||||
/**
|
||||
|
|
@ -22,4 +24,25 @@ class MinuteTest extends AllSetupTeardown
|
|||
{
|
||||
return require 'tests/data/Calculation/DateTime/MINUTE.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerMinuteArray
|
||||
*/
|
||||
public function testMinuteArray(array $expectedResult, string $array): void
|
||||
{
|
||||
$calculation = Calculation::getInstance();
|
||||
|
||||
$formula = "=MINUTE({$array})";
|
||||
$result = $calculation->_calculateFormulaValue($formula);
|
||||
self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14);
|
||||
}
|
||||
|
||||
public function providerMinuteArray(): array
|
||||
{
|
||||
return [
|
||||
'row vector' => [[[2, 14, 20]], '{"2022-02-09 01:02:03", "2022-02-09 13:14:15", "2022-02-09 19:20:21"}'],
|
||||
'column vector' => [[[2], [14], [20]], '{"2022-02-09 01:02:03"; "2022-02-09 13:14:15"; "2022-02-09 19:20:21"}'],
|
||||
'matrix' => [[[2, 14], [20, 59]], '{"2022-02-09 01:02:03", "2022-02-09 13:14:15"; "2022-02-09 19:20:21", "1999-12-31 23:59:59"}'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||
|
||||
class MonthTest extends AllSetupTeardown
|
||||
{
|
||||
/**
|
||||
|
|
@ -22,4 +24,25 @@ class MonthTest extends AllSetupTeardown
|
|||
{
|
||||
return require 'tests/data/Calculation/DateTime/MONTH.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerMonthArray
|
||||
*/
|
||||
public function testMonthArray(array $expectedResult, string $array): void
|
||||
{
|
||||
$calculation = Calculation::getInstance();
|
||||
|
||||
$formula = "=MONTH({$array})";
|
||||
$result = $calculation->_calculateFormulaValue($formula);
|
||||
self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14);
|
||||
}
|
||||
|
||||
public function providerMonthArray(): array
|
||||
{
|
||||
return [
|
||||
'row vector' => [[[1, 6, 1]], '{"2022-01-01", "2022-06-01", "2023-01-01"}'],
|
||||
'column vector' => [[[1], [3], [6]], '{"2022-01-01"; "2022-03-01"; "2022-06-01"}'],
|
||||
'matrix' => [[[1, 4], [8, 12]], '{"2022-01-01", "2022-04-01"; "2022-08-01", "2022-12-01"}'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||
|
||||
class NetworkDaysTest extends AllSetupTeardown
|
||||
{
|
||||
/**
|
||||
|
|
@ -49,4 +51,33 @@ class NetworkDaysTest extends AllSetupTeardown
|
|||
{
|
||||
return require 'tests/data/Calculation/DateTime/NETWORKDAYS.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerNetWorkDaysArray
|
||||
*/
|
||||
public function testNetWorkDaysArray(array $expectedResult, string $startDate, string $endDays, ?string $holidays): void
|
||||
{
|
||||
$calculation = Calculation::getInstance();
|
||||
|
||||
if ($holidays === null) {
|
||||
$formula = "=NETWORKDAYS({$startDate}, {$endDays})";
|
||||
} else {
|
||||
$formula = "=NETWORKDAYS({$startDate}, {$endDays}, {$holidays})";
|
||||
}
|
||||
$result = $calculation->_calculateFormulaValue($formula);
|
||||
self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14);
|
||||
}
|
||||
|
||||
public function providerNetWorkDaysArray(): array
|
||||
{
|
||||
return [
|
||||
'row vector #1' => [[[234, 233, 232]], '{"2022-02-01", "2022-02-02", "2022-02-03"}', '"2022-12-25"', null],
|
||||
'column vector #1' => [[[234], [233], [232]], '{"2022-02-01"; "2022-02-02"; "2022-02-03"}', '"2022-12-25"', null],
|
||||
'matrix #1' => [[[234, 233], [232, 231]], '{"2022-02-01", "2022-02-02"; "2022-02-03", "2022-02-04"}', '"2022-12-25"', null],
|
||||
'row vector #2' => [[[234, -27]], '"2022-02-01"', '{"2022-12-25", "2021-12-25"}', null],
|
||||
'column vector #2' => [[[234], [-27]], '"2022-02-01"', '{"2022-12-25"; "2021-12-25"}', null],
|
||||
'row vector with Holiday' => [[[233, -27]], '"2022-02-01"', '{"2022-12-25", "2021-12-25"}', '{"2022-02-02"}'],
|
||||
'row vector with Holidays' => [[[232, -27]], '"2022-02-01"', '{"2022-12-25", "2021-12-25"}', '{"2022-02-02", "2022-02-03"}'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||
|
||||
class SecondTest extends AllSetupTeardown
|
||||
{
|
||||
/**
|
||||
|
|
@ -22,4 +24,25 @@ class SecondTest extends AllSetupTeardown
|
|||
{
|
||||
return require 'tests/data/Calculation/DateTime/SECOND.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerSecondArray
|
||||
*/
|
||||
public function testSecondArray(array $expectedResult, string $array): void
|
||||
{
|
||||
$calculation = Calculation::getInstance();
|
||||
|
||||
$formula = "=SECOND({$array})";
|
||||
$result = $calculation->_calculateFormulaValue($formula);
|
||||
self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14);
|
||||
}
|
||||
|
||||
public function providerSecondArray(): array
|
||||
{
|
||||
return [
|
||||
'row vector' => [[[3, 15, 21]], '{"2022-02-09 01:02:03", "2022-02-09 13:14:15", "2022-02-09 19:20:21"}'],
|
||||
'column vector' => [[[3], [15], [21]], '{"2022-02-09 01:02:03"; "2022-02-09 13:14:15"; "2022-02-09 19:20:21"}'],
|
||||
'matrix' => [[[3, 15], [21, 59]], '{"2022-02-09 01:02:03", "2022-02-09 13:14:15"; "2022-02-09 19:20:21", "1999-12-31 23:59:59"}'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Time;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
|
||||
class TimeTest extends AllSetupTeardown
|
||||
{
|
||||
|
|
@ -60,4 +62,95 @@ class TimeTest extends AllSetupTeardown
|
|||
$result = Time::fromHMS(0, 0, 0);
|
||||
self::assertEquals(0, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerTimeArray
|
||||
*/
|
||||
public function testTimeArray(array $expectedResult, string $hour, string $minute, string $second): void
|
||||
{
|
||||
$calculation = Calculation::getInstance();
|
||||
|
||||
$formula = "=TIME({$hour}, {$minute}, {$second})";
|
||||
$result = $calculation->_calculateFormulaValue($formula);
|
||||
self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14);
|
||||
}
|
||||
|
||||
public function providerTimeArray(): array
|
||||
{
|
||||
return [
|
||||
'row vector hour' => [[[0.250706018518519, 0.50070601851852, 0.75070601851852]], '{6,12,18}', '1', '1'],
|
||||
'column vector hour' => [[[0.250706018518519], [0.50070601851852], [0.75070601851852]], '{6;12;18}', '1', '1'],
|
||||
'matrix hour' => [[[0.250706018518519, 0.50070601851852], [0.75070601851852, 0.95903935185185]], '{6,12;18,23}', '1', '1'],
|
||||
'row vector minute' => [[[0.96667824074074, 0.97501157407407, 0.98334490740741, 0.99931712962963]], '23', '{12, 24, 36, 59}', '1'],
|
||||
'column vector minute' => [[[0.96734953703704], [0.97568287037037], [0.98401620370370], [0.99998842592593]], '23', '{12; 24; 36; 59}', '59'],
|
||||
'matrix minute' => [[[0.50833333333333, 0.51666666666667], [0.52083333333333, 0.5]], '12', '{12, 24; 30, 0}', '0'],
|
||||
'row vector second' => [[[0.50069444444444, 0.50137731481481]], '12', '1', '{0,59}'],
|
||||
'column vector second' => [[[0.99930555555556], [0.99998842592593]], '23', '59', '{0;59}'],
|
||||
'vectors hour and minute' => [
|
||||
[
|
||||
[0.87570601851852, 0.88473379629630, 0.89376157407407, 0.90626157407407],
|
||||
[0.91737268518519, 0.92640046296296, 0.93542824074074, 0.94792824074074],
|
||||
[0.95903935185185, 0.96806712962963, 0.97709490740741, 0.98959490740741],
|
||||
],
|
||||
'{21;22;23}',
|
||||
'{1, 14, 27, 45}',
|
||||
'1',
|
||||
],
|
||||
'vectors hour and second' => [
|
||||
[
|
||||
[0.126041666666667, 0.126215277777778],
|
||||
[0.334375, 0.33454861111111],
|
||||
[0.584375, 0.58454861111111],
|
||||
],
|
||||
'{3;8;14}',
|
||||
'1',
|
||||
'{30,45}',
|
||||
],
|
||||
'vectors minute and second' => [
|
||||
[
|
||||
[0.75833333333333, 0.75834490740741],
|
||||
[0.76041666666667, 0.76042824074074],
|
||||
[0.77083333333333, 0.77084490740741],
|
||||
[0.75, 0.750011574074074],
|
||||
],
|
||||
'18',
|
||||
'{12; 15; 30; 0}',
|
||||
'{0,1}',
|
||||
],
|
||||
'matrices hour and minute' => [
|
||||
[
|
||||
[0.25070601851852, 0.50278935185185],
|
||||
[0.75487268518519, 0.96528935185185],
|
||||
],
|
||||
'{6, 12; 18, 23}',
|
||||
'{1, 4; 7, 10}',
|
||||
'1',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerTimeArrayException
|
||||
*/
|
||||
public function testTimeArrayException(string $hour, string $minute, string $second): void
|
||||
{
|
||||
$calculation = Calculation::getInstance();
|
||||
|
||||
$this->expectException(Exception::class);
|
||||
$this->expectExceptionMessage('Formulae with more than two array arguments are not supported');
|
||||
|
||||
$formula = "=TIME({$hour}, {$minute}, {$second})";
|
||||
$calculation->_calculateFormulaValue($formula);
|
||||
}
|
||||
|
||||
public function providerTimeArrayException(): array
|
||||
{
|
||||
return [
|
||||
'matrix arguments with 3 array values' => [
|
||||
'{6, 12; 16, 23}',
|
||||
'{1, 4; 7, 10}',
|
||||
'{0,1}',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\TimeValue;
|
||||
|
||||
class TimeValueTest extends AllSetupTeardown
|
||||
|
|
@ -48,4 +49,25 @@ class TimeValueTest extends AllSetupTeardown
|
|||
// ... with the correct value
|
||||
self::assertEquals($result->format('H:i:s'), '07:30:20');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerTimeValueArray
|
||||
*/
|
||||
public function testTimeValueArray(array $expectedResult, string $array): void
|
||||
{
|
||||
$calculation = Calculation::getInstance();
|
||||
|
||||
$formula = "=TIMEVALUE({$array})";
|
||||
$result = $calculation->_calculateFormulaValue($formula);
|
||||
self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14);
|
||||
}
|
||||
|
||||
public function providerTimeValueArray(): array
|
||||
{
|
||||
return [
|
||||
'row vector' => [[[0.04309027777777, 0.5515625, 0.80579861111111]], '{"2022-02-09 01:02:03", "2022-02-09 13:14:15", "2022-02-09 19:20:21"}'],
|
||||
'column vector' => [[[0.04309027777777], [0.5515625], [0.80579861111111]], '{"2022-02-09 01:02:03"; "2022-02-09 13:14:15"; "2022-02-09 19:20:21"}'],
|
||||
'matrix' => [[[0.04309027777777, 0.5515625], [0.80579861111111, 0.99998842592592]], '{"2022-02-09 01:02:03", "2022-02-09 13:14:15"; "2022-02-09 19:20:21", "1999-12-31 23:59:59"}'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Week;
|
||||
|
||||
class WeekDayTest extends AllSetupTeardown
|
||||
|
|
@ -32,4 +33,27 @@ class WeekDayTest extends AllSetupTeardown
|
|||
self::assertEquals(6, Week::day('1904-01-01'));
|
||||
self::assertEquals(6, Week::day(null));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerWeekDayArray
|
||||
*/
|
||||
public function testWeekDayArray(array $expectedResult, string $dateValues, string $styles): void
|
||||
{
|
||||
$calculation = Calculation::getInstance();
|
||||
|
||||
$formula = "=WEEKDAY({$dateValues}, {$styles})";
|
||||
$result = $calculation->_calculateFormulaValue($formula);
|
||||
self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14);
|
||||
}
|
||||
|
||||
public function providerWeekDayArray(): array
|
||||
{
|
||||
return [
|
||||
'row vector #1' => [[[7, 1, 7]], '{"2022-01-01", "2022-06-12", "2023-07-22"}', '1'],
|
||||
'column vector #1' => [[[1], [7], [7]], '{"2023-01-01"; "2023-04-01"; "2023-07-01"}', '1'],
|
||||
'matrix #1' => [[[6, 6], [1, 1]], '{"2021-01-01", "2021-12-31"; "2023-01-01", "2023-12-31"}', '1'],
|
||||
'row vector #2' => [[[7, 6]], '"2022-01-01"', '{1, 2}'],
|
||||
'column vector #2' => [[[1], [7]], '"2023-01-01"', '{1; 2}'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||
|
||||
class WeekNumTest extends AllSetupTeardown
|
||||
{
|
||||
/**
|
||||
|
|
@ -42,4 +44,28 @@ class WeekNumTest extends AllSetupTeardown
|
|||
{
|
||||
return require 'tests/data/Calculation/DateTime/WEEKNUM1904.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerWeekNumArray
|
||||
*/
|
||||
public function testWeekNumArray(array $expectedResult, string $dateValues, string $methods): void
|
||||
{
|
||||
$calculation = Calculation::getInstance();
|
||||
|
||||
$formula = "=WEEKNUM({$dateValues}, {$methods})";
|
||||
$result = $calculation->_calculateFormulaValue($formula);
|
||||
self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14);
|
||||
}
|
||||
|
||||
public function providerWeekNumArray(): array
|
||||
{
|
||||
return [
|
||||
'row vector #1' => [[[1, 25, 29]], '{"2022-01-01", "2022-06-12", "2023-07-22"}', '1'],
|
||||
'column vector #1' => [[[1], [13], [26]], '{"2023-01-01"; "2023-04-01"; "2023-07-01"}', '1'],
|
||||
'matrix #1' => [[[1, 53], [1, 53]], '{"2021-01-01", "2021-12-31"; "2023-01-01", "2023-12-31"}', '1'],
|
||||
'row vector #2' => [[[25, 24]], '"2022-06-12"', '{1, 2}'],
|
||||
'column vector #2' => [[[13], [14]], '"2023-04-01"', '{1; 2}'],
|
||||
'matrix #2' => [[[53, 53], [53, 52]], '"2021-12-31"', '{1, 2; 16, 21}'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"}'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||
|
||||
class YearFracTest extends AllSetupTeardown
|
||||
{
|
||||
/**
|
||||
|
|
@ -41,4 +43,30 @@ class YearFracTest extends AllSetupTeardown
|
|||
{
|
||||
return require 'tests/data/Calculation/DateTime/YEARFRAC.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerYearFracArray
|
||||
*/
|
||||
public function testYearFracArray(array $expectedResult, string $startDate, string $endDate, ?string $methods): void
|
||||
{
|
||||
$calculation = Calculation::getInstance();
|
||||
|
||||
if ($methods === null) {
|
||||
$formula = "=YEARFRAC({$startDate}, {$endDate})";
|
||||
} else {
|
||||
$formula = "=YEARFRAC({$startDate}, {$endDate}, {$methods})";
|
||||
}
|
||||
$result = $calculation->_calculateFormulaValue($formula);
|
||||
self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14);
|
||||
}
|
||||
|
||||
public function providerYearFracArray(): array
|
||||
{
|
||||
return [
|
||||
'row vector #1' => [[[1.0, 0.55277777777778, 0.56111111111111]], '{"2022-01-01", "2022-06-12", "2023-07-22"}', '"2022-12-31"', null],
|
||||
'column vector #1' => [[[1.0], [0.99444444444445], [0.98611111111111]], '{"2022-01-01"; "2022-01-03"; "2022-01-06"}', '"2022-12-31"', null],
|
||||
'matrix #1' => [[[0.002777777777778, 0.027777777777778], [0.625, 1.0]], '{"2022-01-01", "2022-01-10"; "2022-08-15", "2022-12-31"}', '"2021-12-31"', null],
|
||||
'column vector with methods' => [[[0.99726027397260, 0.99722222222222], [0.99178082191781, 0.99166666666667], [0.98356164383562, 0.98333333333333]], '{"2022-01-01"; "2022-01-03"; "2022-01-06"}', '"2022-12-31"', '{1, 4}'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||
|
||||
class YearTest extends AllSetupTeardown
|
||||
{
|
||||
/**
|
||||
|
|
@ -22,4 +24,25 @@ class YearTest extends AllSetupTeardown
|
|||
{
|
||||
return require 'tests/data/Calculation/DateTime/YEAR.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerYearArray
|
||||
*/
|
||||
public function testYearArray(array $expectedResult, string $array): void
|
||||
{
|
||||
$calculation = Calculation::getInstance();
|
||||
|
||||
$formula = "=YEAR({$array})";
|
||||
$result = $calculation->_calculateFormulaValue($formula);
|
||||
self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14);
|
||||
}
|
||||
|
||||
public function providerYearArray(): array
|
||||
{
|
||||
return [
|
||||
'row vector' => [[[2021, 2022, 2023]], '{"2021-01-01", "2022-01-01", "2023-01-01"}'],
|
||||
'column vector' => [[[2021], [2022], [2023]], '{"2021-01-01"; "2022-01-01"; "2023-01-01"}'],
|
||||
'matrix' => [[[2021, 2022], [2023, 1999]], '{"2021-01-01", "2022-01-01"; "2023-01-01", "1999-12-31"}'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue