Files
oleibman 43589bc9b6 Make Base Date a Property of Spreadsheet
This change is extracted from PR #2787 by @MarkBaker. That change mostly deals with array functions, and that part will be superseded by PR #3962. However, this part of 2787 is not included in 3962.

Fix #1036 (closed as stale in 2019 and just reopened). Excel spreadsheets can have either of 2 base dates, 1900 or 1904, and the numeric value of any date cells will vary depending on which base date is in use. PhpSpreadsheet has, till now, handled that as a static property of Shared/Date. This does not work well if two spreadsheets with different base dates are open simultaneously. The code is changed to store the base date as a property of the spreadsheet when an Xls/Xlsx spreadsheet is loaded, and use that property when saving an Xls/Xlsx spreadsheet. Any call to `getCalculatedValue` or `getFormattedValue` will temporarily set the Shared/Date value to that of the spreadsheet, and restore it at completion. In order to avoid a BC break, the Xls and Xlsx readers will continue to populate the Shared/Date value as before.
2024-06-22 22:09:22 -07:00

128 lines
6.2 KiB
PHP

<?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());
$spreadsheet->disconnectWorksheets();
}
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());
$spreadsheet->disconnectWorksheets();
}
public function testNewDateInLoadedExcel1900Spreadsheet(): void
{
$filename = 'tests/data/Reader/XLS/1900_Calendar.xls';
$reader = new Xls();
$spreadsheet = $reader->load($filename);
$worksheet = $spreadsheet->getActiveSheet();
$worksheet->getCell('A4')->setValue('=DATE(2023,1,1)');
self::assertEquals(44927, $worksheet->getCell('A4')->getCalculatedValue());
$spreadsheet->disconnectWorksheets();
}
public function testNewDateInLoadedExcel1904Spreadsheet(): void
{
$filename = 'tests/data/Reader/XLS/1904_Calendar.xls';
$reader = new Xls();
$spreadsheet = $reader->load($filename);
$worksheet = $spreadsheet->getActiveSheet();
$worksheet->getCell('A4')->setValue('=DATE(2023,1,1)');
self::assertEquals(43465, $worksheet->getCell('A4')->getCalculatedValue());
$spreadsheet->disconnectWorksheets();
}
public function testSwitchCalendars(): void
{
$filename1904 = 'tests/data/Reader/XLS/1904_Calendar.xls';
$reader1904 = new Xls();
$spreadsheet1904 = $reader1904->load($filename1904);
$worksheet1904 = $spreadsheet1904->getActiveSheet();
$date1 = Date::convertIsoDate('2022-01-01');
self::assertSame(43100.0, $date1);
$filename1900 = 'tests/data/Reader/XLS/1900_Calendar.xls';
$reader1900 = new Xls();
$spreadsheet1900 = $reader1900->load($filename1900);
$worksheet1900 = $spreadsheet1900->getActiveSheet();
$date2 = Date::convertIsoDate('2022-01-01');
self::assertSame(44562.0, $date2);
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());
$spreadsheet1900->disconnectWorksheets();
$spreadsheet1904->disconnectWorksheets();
}
}