Modify the general settings ExcelCalendar to be simply a default, Create a new ExcelCalendar property for Spreadsheets, and modify the Xlsx and Xls Readers/Writers to maintain 1900 or 1904 calendar against the spreadsheet

This commit is contained in:
MarkBaker
2022-07-10 14:51:05 +02:00
parent 08849a7eee
commit 95cf51b412
6 changed files with 49 additions and 12 deletions
+2 -2
View File
@@ -2026,9 +2026,9 @@ class Xls extends BaseReader
$this->pos += 4 + $length;
// offset: 0; size: 2; 0 = base 1900, 1 = base 1904
Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
$this->spreadsheet->setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
if (ord($recordData[0]) == 1) {
Date::setExcelCalendar(Date::CALENDAR_MAC_1904);
$this->spreadsheet->setExcelCalendar(Date::CALENDAR_MAC_1904);
}
}
+2 -2
View File
@@ -681,11 +681,11 @@ class Xlsx extends BaseReader
// Set base date
if ($xmlWorkbookNS->workbookPr) {
Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
$excel->setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
$attrs1904 = self::getAttributes($xmlWorkbookNS->workbookPr);
if (isset($attrs1904['date1904'])) {
if (self::boolean((string) $attrs1904['date1904'])) {
Date::setExcelCalendar(Date::CALENDAR_MAC_1904);
$excel->setExcelCalendar(Date::CALENDAR_MAC_1904);
}
}
}
+2 -2
View File
@@ -67,7 +67,7 @@ class Date
protected static $defaultTimeZone;
/**
* Set the Excel calendar (Windows 1900 or Mac 1904).
* Set the Excel Default Calendar (Windows 1900 or Mac 1904).
*
* @param int $baseYear Excel base date (1900 or 1904)
*
@@ -85,7 +85,7 @@ class Date
}
/**
* Return the Excel calendar (Windows 1900 or Mac 1904).
* Return the Excel Default Calendar (Windows 1900 or Mac 1904).
*
* @return int Excel base date (1900 or 1904)
*/
+37
View File
@@ -3,6 +3,7 @@
namespace PhpOffice\PhpSpreadsheet;
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
use PhpOffice\PhpSpreadsheet\Shared\Date;
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
use PhpOffice\PhpSpreadsheet\Style\Style;
use PhpOffice\PhpSpreadsheet\Worksheet\Iterator;
@@ -52,6 +53,14 @@ class Spreadsheet
*/
private $workSheetCollection = [];
/**
* Base calendar year to use for calculations
* Value is either CALENDAR_WINDOWS_1900 (1900) or CALENDAR_MAC_1904 (1904).
*
* @var int
*/
protected $excelCalendar = Date::CALENDAR_WINDOWS_1900;
/**
* Calculation Engine.
*
@@ -199,6 +208,34 @@ class Spreadsheet
*/
private $tabRatio = 600;
/**
* Set the Excel Calendar (Windows 1900 or Mac 1904).
*
* @param int $baseYear Excel base date (1900 or 1904)
*
* @return bool Success or failure
*/
public function setExcelCalendar(int $baseYear): bool
{
if (($baseYear == Date::CALENDAR_WINDOWS_1900) || ($baseYear == Date::CALENDAR_MAC_1904)) {
$this->excelCalendar = $baseYear;
return true;
}
return false;
}
/**
* Return the Excel Calendar (Windows 1900 or Mac 1904).
*
* @return int Excel base date (1900 or 1904)
*/
public function getExcelCalendar(): int
{
return $this->excelCalendar;
}
/**
* The workbook has macros ?
*
+3 -3
View File
@@ -960,9 +960,9 @@ class Workbook extends BIFFwriter
$record = 0x0022; // Record identifier
$length = 0x0002; // Bytes to follow
$f1904 = (Date::getExcelCalendar() === Date::CALENDAR_MAC_1904)
? 1
: 0; // Flag for 1904 date system
$f1904 = ($this->spreadsheet->getExcelCalendar() === Date::CALENDAR_MAC_1904)
? 1 // Flag for 1904 date system
: 0; // Flag for 1900 date system
$header = pack('vv', $record, $length);
$data = pack('v', $f1904);
+3 -3
View File
@@ -39,7 +39,7 @@ class Workbook extends WriterPart
$this->writeFileVersion($objWriter);
// workbookPr
$this->writeWorkbookPr($objWriter);
$this->writeWorkbookPr($objWriter, $spreadsheet);
// workbookProtection
$this->writeWorkbookProtection($objWriter, $spreadsheet);
@@ -80,11 +80,11 @@ class Workbook extends WriterPart
/**
* Write WorkbookPr.
*/
private function writeWorkbookPr(XMLWriter $objWriter): void
private function writeWorkbookPr(XMLWriter $objWriter, Spreadsheet $spreadsheet): void
{
$objWriter->startElement('workbookPr');
if (Date::getExcelCalendar() === Date::CALENDAR_MAC_1904) {
if ($spreadsheet->getExcelCalendar() === Date::CALENDAR_MAC_1904) {
$objWriter->writeAttribute('date1904', '1');
}