mirror of
https://github.com/PHPOffice/PhpSpreadsheet.git
synced 2026-09-12 19:16:45 +00:00
Test for calendar when reading Excel Files.
Set Excel calendar to be used for calculations and formatting for the calendar stored against the spreadsheet.
This commit is contained in:
@@ -990,11 +990,6 @@ parameters:
|
||||
count: 6
|
||||
path: src/PhpSpreadsheet/Cell/Cell.php
|
||||
|
||||
-
|
||||
message: "#^Unreachable statement \\- code above always terminates\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Cell/Cell.php
|
||||
|
||||
-
|
||||
message: "#^Call to an undefined method object\\:\\:getHashCode\\(\\)\\.$#"
|
||||
count: 1
|
||||
@@ -2580,11 +2575,6 @@ parameters:
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Shared/OLERead.php
|
||||
|
||||
-
|
||||
message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:_calculateFormulaValue\\(\\)\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Shared/StringHelper.php
|
||||
|
||||
-
|
||||
message: "#^Static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\TimeZone\\:\\:validateTimeZone\\(\\) is unused\\.$#"
|
||||
count: 1
|
||||
|
||||
@@ -15,6 +15,7 @@ use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Style;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
use Throwable;
|
||||
use function _PHPStan_59fb0a3b2\RingCentral\Psr7\str;
|
||||
|
||||
class Cell
|
||||
{
|
||||
@@ -176,16 +177,22 @@ class Cell
|
||||
|
||||
/**
|
||||
* Get cell value with formatting.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFormattedValue()
|
||||
public function getFormattedValue(): string
|
||||
{
|
||||
return (string) NumberFormat::toFormattedString(
|
||||
$currentCalendar = SharedDate::getExcelCalendar();
|
||||
SharedDate::setExcelCalendar($this->getWorksheet()->getParent()->getExcelCalendar());
|
||||
|
||||
$formattedValue = (string) NumberFormat::toFormattedString(
|
||||
$this->getCalculatedValue(),
|
||||
$this->getStyle()
|
||||
->getNumberFormat()->getFormatCode()
|
||||
);
|
||||
|
||||
SharedDate::setExcelCalendar($currentCalendar);
|
||||
|
||||
return $formattedValue;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -342,8 +349,6 @@ class Cell
|
||||
break;
|
||||
default:
|
||||
throw new Exception('Invalid datatype: ' . $dataType);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// set the datatype
|
||||
@@ -403,6 +408,8 @@ class Cell
|
||||
{
|
||||
if ($this->dataType === DataType::TYPE_FORMULA) {
|
||||
try {
|
||||
// $currentCalendar = SharedDate::getExcelCalendar();
|
||||
// SharedDate::setExcelCalendar($this->getWorksheet()->getParent()->getExcelCalendar());
|
||||
$coordinate = $this->getCoordinate();
|
||||
$worksheet = $this->getWorksheet();
|
||||
$value = $this->value;
|
||||
@@ -430,6 +437,7 @@ class Cell
|
||||
$this->getWorksheet()->setSelectedCells($selected);
|
||||
$this->getWorksheet()->getParent()->setActiveSheetIndex($index);
|
||||
} catch (Exception $ex) {
|
||||
// SharedDate::setExcelCalendar($currentCalendar);
|
||||
if (($ex->getMessage() === 'Unable to access External Workbook') && ($this->calculatedValue !== null)) {
|
||||
return $this->calculatedValue; // Fallback for calculations referencing external files.
|
||||
} elseif (preg_match('/[Uu]ndefined (name|offset: 2|array key 2)/', $ex->getMessage()) === 1) {
|
||||
@@ -441,6 +449,7 @@ class Cell
|
||||
);
|
||||
}
|
||||
|
||||
// SharedDate::setExcelCalendar($currentCalendar);
|
||||
if ($result === '#Not Yet Implemented') {
|
||||
return $this->calculatedValue; // Fallback if calculation engine does not support the formula.
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ class Date
|
||||
protected static $defaultTimeZone;
|
||||
|
||||
/**
|
||||
* Set the Excel Default Calendar (Windows 1900 or Mac 1904).
|
||||
* Set the Excel Date Calendar (Windows 1900 or Mac 1904) used for calculations and formatting.
|
||||
*
|
||||
* @param int $baseYear Excel base date (1900 or 1904)
|
||||
*
|
||||
@@ -85,7 +85,8 @@ class Date
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Excel Default Calendar (Windows 1900 or Mac 1904).
|
||||
* Return the Excel Date Calendar (Windows 1900 or Mac 1904)
|
||||
* to be used for current calculations and formatting.
|
||||
*
|
||||
* @return int Excel base date (1900 or 1904)
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Reader\Xls;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Xls;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class DateReaderTest extends TestCase
|
||||
{
|
||||
protected function tearDown(): void
|
||||
{
|
||||
Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
|
||||
}
|
||||
|
||||
public function testReadExcel1900Spreadsheet(): void
|
||||
{
|
||||
$filename = 'tests/data/Reader/XLS/1900_Calendar.xls';
|
||||
$reader = new Xls();
|
||||
$spreadsheet = $reader->load($filename);
|
||||
|
||||
self::assertSame(Date::CALENDAR_WINDOWS_1900, $spreadsheet->getExcelCalendar());
|
||||
|
||||
$worksheet = $spreadsheet->getActiveSheet();
|
||||
self::assertSame(44562, $worksheet->getCell('A1')->getValue());
|
||||
self::assertSame('2022-01-01', $worksheet->getCell('A1')->getFormattedValue());
|
||||
self::assertSame(44926, $worksheet->getCell('A2')->getValue());
|
||||
self::assertSame('2022-12-31', $worksheet->getCell('A2')->getFormattedValue());
|
||||
}
|
||||
|
||||
public function testReadExcel1904Spreadsheet(): void
|
||||
{
|
||||
$filename = 'tests/data/Reader/XLS/1904_Calendar.xls';
|
||||
$reader = new Xls();
|
||||
$spreadsheet = $reader->load($filename);
|
||||
|
||||
self::assertSame(Date::CALENDAR_MAC_1904, $spreadsheet->getExcelCalendar());
|
||||
|
||||
$worksheet = $spreadsheet->getActiveSheet();
|
||||
self::assertSame(43100, $worksheet->getCell('A1')->getValue());
|
||||
self::assertSame('2022-01-01', $worksheet->getCell('A1')->getFormattedValue());
|
||||
self::assertSame(43464, $worksheet->getCell('A2')->getValue());
|
||||
self::assertSame('2022-12-31', $worksheet->getCell('A2')->getFormattedValue());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Reader\Xlsx;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class DateReaderTest extends TestCase
|
||||
{
|
||||
protected function tearDown(): void
|
||||
{
|
||||
Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
|
||||
}
|
||||
|
||||
public function testReadExcel1900Spreadsheet(): void
|
||||
{
|
||||
$filename = 'tests/data/Reader/XLSX/1900_Calendar.xlsx';
|
||||
$reader = new Xlsx();
|
||||
$spreadsheet = $reader->load($filename);
|
||||
|
||||
self::assertSame(Date::CALENDAR_WINDOWS_1900, $spreadsheet->getExcelCalendar());
|
||||
|
||||
$worksheet = $spreadsheet->getActiveSheet();
|
||||
self::assertSame(44562, $worksheet->getCell('A1')->getValue());
|
||||
self::assertSame('2022-01-01', $worksheet->getCell('A1')->getFormattedValue());
|
||||
self::assertSame(44926, $worksheet->getCell('A2')->getValue());
|
||||
self::assertSame('2022-12-31', $worksheet->getCell('A2')->getFormattedValue());
|
||||
self::assertSame(44561, $worksheet->getCell('B1')->getCalculatedValue());
|
||||
self::assertSame('2021-12-31', $worksheet->getCell('B1')->getFormattedValue());
|
||||
self::assertSame(44927, $worksheet->getCell('B2')->getCalculatedValue());
|
||||
self::assertSame('2023-01-01', $worksheet->getCell('B2')->getFormattedValue());
|
||||
}
|
||||
|
||||
public function testReadExcel1904Spreadsheet(): void
|
||||
{
|
||||
$filename = 'tests/data/Reader/XLSX/1904_Calendar.xlsx';
|
||||
$reader = new Xlsx();
|
||||
$spreadsheet = $reader->load($filename);
|
||||
|
||||
self::assertSame(Date::CALENDAR_MAC_1904, $spreadsheet->getExcelCalendar());
|
||||
|
||||
$worksheet = $spreadsheet->getActiveSheet();
|
||||
self::assertSame(43100, $worksheet->getCell('A1')->getValue());
|
||||
self::assertSame('2022-01-01', $worksheet->getCell('A1')->getFormattedValue());
|
||||
self::assertSame(43464, $worksheet->getCell('A2')->getValue());
|
||||
self::assertSame('2022-12-31', $worksheet->getCell('A2')->getFormattedValue());
|
||||
self::assertSame(43099, $worksheet->getCell('B1')->getCalculatedValue());
|
||||
self::assertSame('2021-12-31', $worksheet->getCell('B1')->getFormattedValue());
|
||||
self::assertSame(43465, $worksheet->getCell('B2')->getCalculatedValue());
|
||||
self::assertSame('2023-01-01', $worksheet->getCell('B2')->getFormattedValue());
|
||||
}
|
||||
|
||||
public function testSwitchCalendars(): void
|
||||
{
|
||||
$filename1900 = 'tests/data/Reader/XLSX/1900_Calendar.xlsx';
|
||||
$reader1900 = new Xlsx();
|
||||
$spreadsheet1900 = $reader1900->load($filename1900);
|
||||
$worksheet1900 = $spreadsheet1900->getActiveSheet();
|
||||
|
||||
$filename1904 = 'tests/data/Reader/XLSX/1904_Calendar.xlsx';
|
||||
$reader1904 = new Xlsx();
|
||||
$spreadsheet1904 = $reader1904->load($filename1904);
|
||||
$worksheet1904 = $spreadsheet1904->getActiveSheet();
|
||||
|
||||
self::assertSame(44562, $worksheet1900->getCell('A1')->getValue());
|
||||
self::assertSame('2022-01-01', $worksheet1900->getCell('A1')->getFormattedValue());
|
||||
self::assertSame(44926, $worksheet1900->getCell('A2')->getValue());
|
||||
self::assertSame('2022-12-31', $worksheet1900->getCell('A2')->getFormattedValue());
|
||||
self::assertSame(44561, $worksheet1900->getCell('B1')->getCalculatedValue());
|
||||
self::assertSame('2021-12-31', $worksheet1900->getCell('B1')->getFormattedValue());
|
||||
self::assertSame(44927, $worksheet1900->getCell('B2')->getCalculatedValue());
|
||||
self::assertSame('2023-01-01', $worksheet1900->getCell('B2')->getFormattedValue());
|
||||
|
||||
self::assertSame(43100, $worksheet1904->getCell('A1')->getValue());
|
||||
self::assertSame('2022-01-01', $worksheet1904->getCell('A1')->getFormattedValue());
|
||||
self::assertSame(43464, $worksheet1904->getCell('A2')->getValue());
|
||||
self::assertSame('2022-12-31', $worksheet1904->getCell('A2')->getFormattedValue());
|
||||
self::assertSame(43099, $worksheet1904->getCell('B1')->getCalculatedValue());
|
||||
self::assertSame('2021-12-31', $worksheet1904->getCell('B1')->getFormattedValue());
|
||||
self::assertSame(43465, $worksheet1904->getCell('B2')->getCalculatedValue());
|
||||
self::assertSame('2023-01-01', $worksheet1904->getCell('B2')->getFormattedValue());
|
||||
|
||||
// Check that accessing date values from one spreadsheet doesn't break accessing correct values from another
|
||||
self::assertSame(44561, $worksheet1900->getCell('B1')->getCalculatedValue());
|
||||
self::assertSame('2021-12-31', $worksheet1900->getCell('B1')->getFormattedValue());
|
||||
self::assertSame(44927, $worksheet1900->getCell('B2')->getCalculatedValue());
|
||||
self::assertSame('2023-01-01', $worksheet1900->getCell('B2')->getFormattedValue());
|
||||
self::assertSame(44562, $worksheet1900->getCell('A1')->getValue());
|
||||
self::assertSame('2022-01-01', $worksheet1900->getCell('A1')->getFormattedValue());
|
||||
self::assertSame(44926, $worksheet1900->getCell('A2')->getValue());
|
||||
self::assertSame('2022-12-31', $worksheet1900->getCell('A2')->getFormattedValue());
|
||||
|
||||
self::assertSame(43099, $worksheet1904->getCell('B1')->getCalculatedValue());
|
||||
self::assertSame('2021-12-31', $worksheet1904->getCell('B1')->getFormattedValue());
|
||||
self::assertSame(43465, $worksheet1904->getCell('B2')->getCalculatedValue());
|
||||
self::assertSame('2023-01-01', $worksheet1904->getCell('B2')->getFormattedValue());
|
||||
self::assertSame(43100, $worksheet1904->getCell('A1')->getValue());
|
||||
self::assertSame('2022-01-01', $worksheet1904->getCell('A1')->getFormattedValue());
|
||||
self::assertSame(43464, $worksheet1904->getCell('A2')->getValue());
|
||||
self::assertSame('2022-12-31', $worksheet1904->getCell('A2')->getFormattedValue());
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user