mirror of
https://github.com/PHPOffice/PhpSpreadsheet.git
synced 2026-09-11 18:46:49 +00:00
11854514a0
* Changes to NUMBERVALUE, VALUE, DATEVALUE, TIMEVALUE Fix #3574. Reporter received deprecation notice for NUMBERVALUE function with invalid arguments. In fact, the arguments turn out to be valid after all; NUMBERVALUE treats a null-string or an all-blank-string in the first argument as if it were 0. Fixed this, and added several test cases suggested by it. VALUE had been parsing its argument the same way as NUMBERVALUE. However, VALUE does not substitute 0 for null-string or all-blank-string. Coded up the difference between the two, and added the same tests for VALUE as for NUMBERVALUE. VALUE can also pass its argument to DATEVALUE or TIMEVALUE. It is currently over-permissive about that, because Php is over-permissive, e.g. `new DateTime('q')` will return a DateTime object with the current date and time with a timezone of 'q'. Excel will, naturally, return `#VALUE!` for `DATEVALUE('q')`. I don't know that we can ever match Excel's (AFAIK not formally documented) decisions here 100%, but we can get a lot closer by parsing the date string if and only if it contains at least one digit. Code to enforce that is added to DATEVALUE and TIMEVALUE, and appropriate tests are added. * Failure for Php 7.4 Linux After not seeing any such problem for many months, this is the second day in a row where result is different on Windows than Linux with no apparent reason to think why that should be the case. At any rate, easily solved.
169 lines
5.4 KiB
PHP
169 lines
5.4 KiB
PHP
<?php
|
|
|
|
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
|
|
|
|
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
|
use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\TimeValue;
|
|
use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalculationException;
|
|
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
|
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
|
use PhpOffice\PhpSpreadsheetTests\Calculation\Functions\FormulaArguments;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
class TimeValueTest extends TestCase
|
|
{
|
|
/**
|
|
* @var string
|
|
*/
|
|
private $returnDateType;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
$this->returnDateType = Functions::getReturnDateType();
|
|
}
|
|
|
|
protected function tearDown(): void
|
|
{
|
|
parent::tearDown();
|
|
|
|
Functions::setReturnDateType($this->returnDateType);
|
|
}
|
|
|
|
/**
|
|
* @dataProvider providerTIMEVALUE
|
|
*
|
|
* @param mixed $expectedResult
|
|
*/
|
|
public function testDirectCallToTIMEVALUE($expectedResult, ...$args): void
|
|
{
|
|
/** @scrutinizer ignore-call */
|
|
$result = TimeValue::fromString(...$args);
|
|
self::assertEqualsWithDelta($expectedResult, $result, 1.0e-8);
|
|
}
|
|
|
|
/**
|
|
* @dataProvider providerTIMEVALUE
|
|
*
|
|
* @param mixed $expectedResult
|
|
*/
|
|
public function testTIMEVALUEAsFormula($expectedResult, ...$args): void
|
|
{
|
|
$arguments = new FormulaArguments(...$args);
|
|
|
|
$calculation = Calculation::getInstance();
|
|
$formula = "=TIMEVALUE({$arguments})";
|
|
|
|
$result = $calculation->_calculateFormulaValue($formula);
|
|
self::assertEqualsWithDelta($expectedResult, $result, 1.0e-8);
|
|
}
|
|
|
|
/**
|
|
* @dataProvider providerTIMEVALUE
|
|
*
|
|
* @param mixed $expectedResult
|
|
*/
|
|
public function testTIMEVALUEInWorksheet($expectedResult, ...$args): void
|
|
{
|
|
$arguments = new FormulaArguments(...$args);
|
|
|
|
$spreadsheet = new Spreadsheet();
|
|
$worksheet = $spreadsheet->getActiveSheet();
|
|
$argumentCells = $arguments->populateWorksheet($worksheet);
|
|
$formula = "=TIMEVALUE({$argumentCells})";
|
|
|
|
$result = $worksheet->setCellValue('A1', $formula)
|
|
->getCell('A1')
|
|
->getCalculatedValue();
|
|
self::assertEqualsWithDelta($expectedResult, $result, 1.0e-8);
|
|
|
|
$spreadsheet->disconnectWorksheets();
|
|
}
|
|
|
|
public static function providerTIMEVALUE(): array
|
|
{
|
|
return require 'tests/data/Calculation/DateTime/TIMEVALUE.php';
|
|
}
|
|
|
|
public function testRefArgNull(): void
|
|
{
|
|
$spreadsheet = new Spreadsheet();
|
|
$sheet = $spreadsheet->getActiveSheet();
|
|
$sheet->getCell('A1')->setValue('=TIMEVALUE(B1)');
|
|
self::assertSame('#VALUE!', $sheet->getCell('A1')->getCalculatedValue());
|
|
$spreadsheet->disconnectWorksheets();
|
|
}
|
|
|
|
public function testTIMEVALUEtoUnixTimestamp(): void
|
|
{
|
|
Functions::setReturnDateType(Functions::RETURNDATE_UNIX_TIMESTAMP);
|
|
|
|
$result = TimeValue::fromString('7:30:20');
|
|
self::assertEquals(23420, $result);
|
|
self::assertEqualsWithDelta(23420, $result, 1.0e-8);
|
|
}
|
|
|
|
public function testTIMEVALUEtoDateTimeObject(): void
|
|
{
|
|
Functions::setReturnDateType(Functions::RETURNDATE_PHP_DATETIME_OBJECT);
|
|
|
|
$result = TimeValue::fromString('7:30:20');
|
|
// Must return an object...
|
|
self::assertIsObject($result);
|
|
// ... of the correct type
|
|
self::assertTrue(is_a($result, 'DateTimeInterface'));
|
|
// ... with the correct value
|
|
self::assertEquals($result->format('H:i:s'), '07:30:20');
|
|
}
|
|
|
|
/**
|
|
* @dataProvider providerUnhappyTIMEVALUE
|
|
*/
|
|
public function testTIMEVALUEUnhappyPath(string $expectedException, ...$args): void
|
|
{
|
|
$arguments = new FormulaArguments(...$args);
|
|
|
|
$spreadsheet = new Spreadsheet();
|
|
$worksheet = $spreadsheet->getActiveSheet();
|
|
$argumentCells = $arguments->populateWorksheet($worksheet);
|
|
$formula = "=TIMEVALUE({$argumentCells})";
|
|
|
|
$this->expectException(CalculationException::class);
|
|
$this->expectExceptionMessage($expectedException);
|
|
$worksheet->setCellValue('A1', $formula)
|
|
->getCell('A1')
|
|
->getCalculatedValue();
|
|
|
|
$spreadsheet->disconnectWorksheets();
|
|
}
|
|
|
|
public static function providerUnhappyTIMEVALUE(): array
|
|
{
|
|
return [
|
|
['Formula Error: Wrong number of arguments for TIMEVALUE() function'],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @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 static 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"}'],
|
|
];
|
|
}
|
|
}
|