diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index eb111437..0d771ff7 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -4477,7 +4477,7 @@ class Calculation } // if the token is a binary operator, pop the top two values off the stack, do the operation, and push the result back on the stack - if (isset(self::$binaryOperators[$token])) { + if (!is_numeric($token) && isset(self::$binaryOperators[$token])) { // We must have two operands, error if we don't if (($operand2Data = $stack->pop()) === null) { return $this->raiseFormulaError('Internal error - Operand value missing from stack'); diff --git a/src/PhpSpreadsheet/Shared/OLE.php b/src/PhpSpreadsheet/Shared/OLE.php index 8ecfc6be..6278553f 100644 --- a/src/PhpSpreadsheet/Shared/OLE.php +++ b/src/PhpSpreadsheet/Shared/OLE.php @@ -502,9 +502,6 @@ class OLE } $dateTime = Date::dateTimeFromTimestamp("$date"); - // factor used for separating numbers into 4 bytes parts - $factor = 2 ** 32; - // days from 1-1-1601 until the beggining of UNIX era $days = 134774; // calculate seconds @@ -512,22 +509,15 @@ class OLE // multiply just to make MS happy $big_date *= 10000000; - $high_part = floor($big_date / $factor); - // lower 4 bytes - $low_part = floor((($big_date / $factor) - $high_part) * $factor); - // Make HEX string $res = ''; - for ($i = 0; $i < 4; ++$i) { - $hex = $low_part % 0x100; - $res .= pack('c', $hex); - $low_part /= 0x100; - } - for ($i = 0; $i < 4; ++$i) { - $hex = $high_part % 0x100; - $res .= pack('c', $hex); - $high_part /= 0x100; + $factor = 2 ** 56; + while ($factor >= 1) { + $hex = (int) floor($big_date / $factor); + $res = pack('c', $hex) . $res; + $big_date = fmod($big_date, $factor); + $factor /= 256; } return $res; diff --git a/src/PhpSpreadsheet/Writer/Xlsx/StringTable.php b/src/PhpSpreadsheet/Writer/Xlsx/StringTable.php index b0f7d6d4..b73d53cc 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/StringTable.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/StringTable.php @@ -42,8 +42,8 @@ class StringTable extends WriterPart !is_object($cellValue) && ($cellValue !== null) && $cellValue !== '' && - !isset($aFlippedStringTable[$cellValue]) && - ($cell->getDataType() == DataType::TYPE_STRING || $cell->getDataType() == DataType::TYPE_STRING2 || $cell->getDataType() == DataType::TYPE_NULL) + ($cell->getDataType() == DataType::TYPE_STRING || $cell->getDataType() == DataType::TYPE_STRING2 || $cell->getDataType() == DataType::TYPE_NULL) && + !isset($aFlippedStringTable[$cellValue]) ) { $aStringTable[] = $cellValue; $aFlippedStringTable[$cellValue] = true; diff --git a/tests/PhpSpreadsheetTests/Document/EpochTest.php b/tests/PhpSpreadsheetTests/Document/EpochTest.php index 63c51a59..5ea5c5a8 100644 --- a/tests/PhpSpreadsheetTests/Document/EpochTest.php +++ b/tests/PhpSpreadsheetTests/Document/EpochTest.php @@ -11,10 +11,13 @@ class EpochTest extends AbstractFunctional public function providerFormats(): array { return [ + ['Ods', '1921-03-17 11:30:00Z'], ['Ods', '2021-03-17 11:30:00Z'], ['Ods', '2041-03-17 11:30:00Z'], + ['Xls', '1921-03-17 11:30:00Z'], ['Xls', '2021-03-17 11:30:00Z'], ['Xls', '2041-03-17 11:30:00Z'], + ['Xlsx', '1921-03-17 11:30:00Z'], ['Xlsx', '2021-03-17 11:30:00Z'], ['Xlsx', '2041-03-17 11:30:00Z'], ];