Skip to content

Commit 2bc326b

Browse files
authored
Merge branch 'master' into issue4695
2 parents 4833efc + 4f6c850 commit 2bc326b

File tree

21 files changed

+274
-80
lines changed

21 files changed

+274
-80
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org). Thia is a
3030
### Fixed
3131

3232
- Protected ranges and insert/delete rows/columns. [Issue #4695](https://github.com/PHPOffice/PhpSpreadsheet/issues/4695) [PR #4702](https://github.com/PHPOffice/PhpSpreadsheet/pull/4702)
33+
- Unexpected Exception in Php DateTime. [Issue #4696](https://github.com/PHPOffice/PhpSpreadsheet/issues/4696) [Issue #917](https://github.com/PHPOffice/PhpSpreadsheet/issues/917) [PR #4697](https://github.com/PHPOffice/PhpSpreadsheet/pull/4697)
3334

3435
## 2025-10-25 - 5.2.0
3536

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@
103103
"tecnickcom/tcpdf": "^6.5"
104104
},
105105
"suggest": {
106-
"ext-intl": "PHP Internationalization Functions, regquired for NumberFormat Wizard",
106+
"ext-intl": "PHP Internationalization Functions, required for NumberFormat Wizard",
107107
"mpdf/mpdf": "Option for rendering PDF with PDF Writer",
108108
"dompdf/dompdf": "Option for rendering PDF with PDF Writer",
109109
"tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer",

composer.lock

Lines changed: 28 additions & 34 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/topics/autofilters.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ $columnFilter->createRule()
176176
In MS Excel, DateGroup filters provide a series of dropdown filter
177177
selectors for date values, so you can specify entire years, or months
178178
within a year, or individual days within each month.
179+
Note that cells covered by such a filter are expected to be in [Excel DateTime Format](./calculation-engine.md#excel-timestamps).
179180

180181
![04-02-dategroup-autofilter.png](./images/04-02-dategroup-autofilter.png)
181182

docs/topics/calculation-engine.md

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -194,20 +194,22 @@ Time functions in Excel will be a PHP `DateTime` object.
194194

195195
#### Excel Timestamps
196196

197-
If `RETURNDATE_EXCEL` is set for the Return Date Type, then the returned
198-
date value by any access to the Date and Time functions in Excel will be
199-
a floating point value that represents a number of days from the Excel
200-
base date. The Excel base date is determined by which calendar Excel
197+
Excel timestamps are stored as integer or floating point, where the integer portion represents the number of days since a base date,
198+
and the fraction portion represents the time of day (0 is midnight, 0.5 is noon, 0.999... is just before midnight the next day).
199+
The Excel base date is determined by which calendar Excel
201200
uses: the Windows 1900 or the Mac 1904 calendar. 1st January 1900 is the
202201
base date for the Windows 1900 calendar while 1st January 1904 is the
203202
base date for the Mac 1904 calendar.
204203

205-
It is possible for scripts to change the calendar used for calculating
206-
Excel date values by calling the
207-
`\PhpOffice\PhpSpreadsheet\Shared\Date::setExcelCalendar()` method:
204+
If `RETURNDATE_EXCEL` is set for the Return Date Type, then the returned
205+
date value by any access to the Date and Time functions in Excel will be
206+
a floating point value in Excel timestamp format (previous paragraph).
208207

208+
It is possible for scripts to change the calendar used for calculating
209+
Excel date values by calling:
209210
```php
210-
\PhpOffice\PhpSpreadsheet\Shared\Date::setExcelCalendar($baseDate);
211+
\PhpOffice\PhpSpreadsheet\Shared\Date::setExcelCalendar($baseDate); // static property, less preferred
212+
$spreadsheet->setExcelCalendar($baseDate); // instance property, preferred
211213
```
212214

213215
where the following constants can be used for `$baseDate`:
@@ -218,11 +220,10 @@ where the following constants can be used for `$baseDate`:
218220
The method will return a Boolean True on success, False on failure (e.g.
219221
if an invalid value is passed in).
220222

221-
The `\PhpOffice\PhpSpreadsheet\Shared\Date::getExcelCalendar()` method can
222-
be used to determine the current value of this setting:
223-
223+
The current value of this setting can be determined via:
224224
```php
225-
$baseDate = \PhpOffice\PhpSpreadsheet\Shared\Date::getExcelCalendar();
225+
$baseDate = \PhpOffice\PhpSpreadsheet\Shared\Date::getExcelCalendar(); // static
226+
$baseDate = $spreadsheet->getExcelCalendar(); // instance
226227
```
227228

228229
The default is `CALENDAR_WINDOWS_1900`.

src/PhpSpreadsheet/Calculation/Calculation.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2581,6 +2581,8 @@ public function extractCellRange(string &$range = 'A1', ?Worksheet $worksheet =
25812581
if (!isset($aReferences[1])) {
25822582
// Single cell in range
25832583
sscanf($aReferences[0], '%[A-Z]%d', $currentCol, $currentRow);
2584+
/** @var string $currentCol */
2585+
/** @var int $currentRow */
25842586
if ($createCell && $worksheet !== null && !$worksheet->cellExists($aReferences[0])) {
25852587
$worksheet->setCellValue($aReferences[0], null);
25862588
}
@@ -2600,6 +2602,8 @@ public function extractCellRange(string &$range = 'A1', ?Worksheet $worksheet =
26002602
foreach ($aReferences as $reference) {
26012603
// Extract range
26022604
sscanf($reference, '%[A-Z]%d', $currentCol, $currentRow);
2605+
/** @var string $currentCol */
2606+
/** @var int $currentRow */
26032607
if ($createCell && $worksheet !== null && !$worksheet->cellExists($reference)) {
26042608
$worksheet->setCellValue($reference, null);
26052609
}

src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
88
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
99
use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDateHelper;
10+
use Throwable;
1011

1112
class Helpers
1213
{
@@ -56,6 +57,12 @@ public static function getDateValue(mixed $dateValue, bool $allowBool = true): f
5657
throw new Exception(ExcelError::NAN());
5758
}
5859

60+
try {
61+
SharedDateHelper::excelToDateTimeObject((float) $dateValue);
62+
} catch (Throwable) {
63+
throw new Exception(ExcelError::NAN());
64+
}
65+
5966
return (float) $dateValue;
6067
}
6168

src/PhpSpreadsheet/Calculation/DateTimeExcel/TimeParts.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44

55
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
66
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
7+
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
78
use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDateHelper;
9+
use Throwable;
810

911
class TimeParts
1012
{
@@ -44,6 +46,11 @@ public static function hour(mixed $timeValue): array|string|int
4446
}
4547

4648
// Execute function
49+
try {
50+
SharedDateHelper::excelToDateTimeObject($timeValue);
51+
} catch (Throwable) {
52+
return ExcelError::NAN();
53+
}
4754
$timeValue = fmod($timeValue, 1);
4855
$timeValue = SharedDateHelper::excelToDateTimeObject($timeValue);
4956
SharedDateHelper::roundMicroseconds($timeValue);
@@ -85,6 +92,11 @@ public static function minute(mixed $timeValue): array|string|int
8592
}
8693

8794
// Execute function
95+
try {
96+
SharedDateHelper::excelToDateTimeObject($timeValue);
97+
} catch (Throwable) {
98+
return ExcelError::NAN();
99+
}
88100
$timeValue = fmod($timeValue, 1);
89101
$timeValue = SharedDateHelper::excelToDateTimeObject($timeValue);
90102
SharedDateHelper::roundMicroseconds($timeValue);
@@ -126,6 +138,11 @@ public static function second(mixed $timeValue): array|string|int
126138
}
127139

128140
// Execute function
141+
try {
142+
SharedDateHelper::excelToDateTimeObject($timeValue);
143+
} catch (Throwable) {
144+
return ExcelError::NAN();
145+
}
129146
$timeValue = fmod($timeValue, 1);
130147
$timeValue = SharedDateHelper::excelToDateTimeObject($timeValue);
131148
SharedDateHelper::roundMicroseconds($timeValue);

src/PhpSpreadsheet/Calculation/LookupRef/Lookup.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ public static function lookup(mixed $lookupValue, mixed $lookupVector, $resultVe
4747
$lookupVector = array_shift($lookupVector);
4848
}
4949

50-
/** @var mixed[] $lookupVector */
51-
/** @var mixed[] $resultVector */
50+
/** @var array<int, mixed> $lookupVector */
51+
/** @var array<int, mixed> $resultVector */
5252
if ($lookupColumns !== 2) {
5353
$lookupVector = self::verifyLookupValues($lookupVector, $resultVector);
5454
}
@@ -57,8 +57,8 @@ public static function lookup(mixed $lookupValue, mixed $lookupVector, $resultVe
5757
}
5858

5959
/**
60-
* @param mixed[] $lookupVector
61-
* @param mixed[] $resultVector
60+
* @param array<int, mixed> $lookupVector
61+
* @param array<int, mixed> $resultVector
6262
*
6363
* @return mixed[]
6464
*/
@@ -80,6 +80,7 @@ private static function verifyLookupValues(array $lookupVector, array $resultVec
8080
if (is_array($dataValue2)) {
8181
$dataValue2 = array_shift($dataValue2);
8282
}
83+
/** @var int $key2 */
8384
$value = [$key1 => $dataValue1, $key2 => $dataValue2];
8485
}
8586
unset($value);

src/PhpSpreadsheet/Calculation/LookupRef/Matrix.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ public static function index(mixed $matrix, mixed $rowNum = 0, mixed $columnNum
150150

151151
/**
152152
* @param mixed[] $matrix
153-
* @param mixed[] $rowKeys
153+
* @param array<int, int> $rowKeys
154154
*/
155155
private static function extractRowValue(array $matrix, array $rowKeys, int $rowNum): mixed
156156
{
@@ -159,7 +159,7 @@ private static function extractRowValue(array $matrix, array $rowKeys, int $rowN
159159
}
160160

161161
$rowNum = $rowKeys[--$rowNum];
162-
$row = $matrix[$rowNum]; //* @phpstan-ignore-line
162+
$row = $matrix[$rowNum];
163163
if (is_array($row)) {
164164
return [$rowNum => $row];
165165
}

0 commit comments

Comments
 (0)