Skip to content

Commit d7b2b11

Browse files
committed
DateTime: triggers a warning when time overflow occurs
The next version will throw an exception
1 parent 54042c6 commit d7b2b11

File tree

4 files changed

+96
-0
lines changed

4 files changed

+96
-0
lines changed

src/Utils/DateTime.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,43 @@ public static function createFromFormat(
108108
}
109109

110110

111+
public function __construct(string $datetime = 'now', ?\DateTimeZone $timezone = null)
112+
{
113+
parent::__construct($datetime, $timezone);
114+
$this->handleErrors($datetime);
115+
}
116+
117+
118+
public function modify(string $modifier): static
119+
{
120+
parent::modify($modifier) && $this->handleErrors($modifier);
121+
return $this;
122+
}
123+
124+
125+
public function setDate(int $year, int $month, int $day): static
126+
{
127+
if (!checkdate($month, $day, $year)) {
128+
trigger_error(sprintf(self::class . ': The date %04d-%02d-%02d is not valid.', $year, $month, $day), E_USER_WARNING);
129+
}
130+
return parent::setDate($year, $month, $day);
131+
}
132+
133+
134+
public function setTime(int $hour, int $minute, int $second = 0, int $microsecond = 0): static
135+
{
136+
if (
137+
$hour < 0 || $hour > 23
138+
|| $minute < 0 || $minute > 59
139+
|| $second < 0 || $second >= 60
140+
|| $microsecond < 0 || $microsecond >= 1_000_000
141+
) {
142+
trigger_error(sprintf(self::class . ': The time %02d:%02d:%08.5F is not valid.', $hour, $minute, $second + $microsecond / 1_000_000), E_USER_WARNING);
143+
}
144+
return parent::setTime($hour, $minute, $second, $microsecond);
145+
}
146+
147+
111148
/**
112149
* Returns JSON representation in ISO 8601 (used by JavaScript).
113150
*/
@@ -134,4 +171,14 @@ public function modifyClone(string $modify = ''): static
134171
$dolly = clone $this;
135172
return $modify ? $dolly->modify($modify) : $dolly;
136173
}
174+
175+
176+
private function handleErrors(string $value): void
177+
{
178+
$errors = self::getLastErrors();
179+
$errors = array_merge($errors['errors'] ?? [], $errors['warnings'] ?? []);
180+
if ($errors) {
181+
trigger_error(self::class . ': ' . implode(', ', $errors) . " '$value'", E_USER_WARNING);
182+
}
183+
}
137184
}

tests/Utils/DateTime.construct.phpt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,4 +100,22 @@ test('Exception handling for invalid input', function () {
100100
Throwable::class,
101101
'%a%invalid date format%a%',
102102
);
103+
104+
Assert::error(
105+
fn() => new DateTime('0000-00-00'),
106+
E_USER_WARNING,
107+
"Nette\\Utils\\DateTime: The parsed date was invalid '0000-00-00'",
108+
);
109+
110+
Assert::error(
111+
fn() => new DateTime('2024-02-31 10:00:00'), // Invalid day for February
112+
E_USER_WARNING,
113+
"Nette\\Utils\\DateTime: The parsed date was invalid '2024-02-31 10:00:00'",
114+
);
115+
116+
Assert::error(
117+
fn() => new DateTime('1978-01-23 23:00:60'),
118+
E_USER_WARNING,
119+
"Nette\\Utils\\DateTime: The parsed time was invalid '1978-01-23 23:00:60'",
120+
);
103121
});

tests/Utils/DateTime.modify.phpt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,4 +112,10 @@ test('Invalid modifier format exceptions', function () {
112112
'DateTime::modify(): Failed to parse time string (+) at position 0 (+): Unexpected character',
113113
);
114114
}
115+
116+
Assert::error(
117+
fn() => (new DateTime)->modify('2024-02-31 10:00:00'), // Invalid day for February
118+
E_USER_WARNING,
119+
"Nette\\Utils\\DateTime: The parsed date was invalid '2024-02-31 10:00:00'",
120+
);
115121
});

tests/Utils/DateTime.setDateTime.phpt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
/**
4+
* Test: Nette\Utils\DateTime: strict.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
use Nette\Utils\DateTime;
10+
use Tester\Assert;
11+
12+
require __DIR__ . '/../bootstrap.php';
13+
14+
15+
Assert::error(
16+
fn() => (new DateTime)->setDate(1978, 2, 31),
17+
E_USER_WARNING,
18+
'Nette\Utils\DateTime: The date 1978-02-31 is not valid.',
19+
);
20+
21+
Assert::error(
22+
fn() => (new DateTime)->setTime(0, 60),
23+
E_USER_WARNING,
24+
'Nette\Utils\DateTime: The time 00:60:00.00000 is not valid.',
25+
);

0 commit comments

Comments
 (0)