Skip to content

Commit 97b0aa2

Browse files
committed
Allow disabling lenient IntlDateFormatter parsing
1 parent 2b5fa82 commit 97b0aa2

File tree

3 files changed

+81
-1
lines changed

3 files changed

+81
-1
lines changed

src/I18n/DateFormatTrait.php

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,15 @@ trait DateFormatTrait
4242
*/
4343
protected static $defaultLocale;
4444

45+
/**
46+
* Whether the IntlDateFormatter is set to lenient for parsing.
47+
*
48+
* Defaults to null which uses IntlDateFormatter default (true).
49+
*
50+
* @var bool|null
51+
*/
52+
protected static $lenientParse;
53+
4554
/**
4655
* In-memory cache of date formatters
4756
*
@@ -69,14 +78,39 @@ public static function getDefaultLocale(): ?string
6978
/**
7079
* Sets the default locale.
7180
*
72-
* @param string|null $locale The default locale string to be used or null.
81+
* Set to null to use IntlDateFormatter default.
82+
*
83+
* @param string|null $locale The default locale string to be used.
7384
* @return void
7485
*/
7586
public static function setDefaultLocale(?string $locale = null): void
7687
{
7788
static::$defaultLocale = $locale;
7889
}
7990

91+
/**
92+
* Gets whether i18n parsing is set to lenient.
93+
*
94+
* Returns null when the default for IntlDateFormatter is used.
95+
*
96+
* @return bool|null
97+
*/
98+
public static function getLenientParse(): ?bool
99+
{
100+
return static::$lenientParse;
101+
}
102+
103+
/**
104+
* Sets whether i18n parsing is lenient.
105+
*
106+
* @param bool|null $lenient Whether IntlDateFormatter is set to lenient
107+
* @return void
108+
*/
109+
public static function setLenientParse(?bool $lenient = null): void
110+
{
111+
static::$lenientParse = $lenient;
112+
}
113+
80114
/**
81115
* Returns a nicely formatted date string for this object.
82116
*
@@ -335,6 +369,10 @@ public static function parseDateTime(string $time, $format = null, $tz = null)
335369
null,
336370
$pattern ?? ''
337371
);
372+
if (static::$lenientParse !== null) {
373+
$formatter->setLenient(static::$lenientParse);
374+
}
375+
338376
$time = $formatter->parse($time);
339377
if ($time !== false) {
340378
$dateTime = new DateTime('@' . $time);

tests/TestCase/I18n/DateTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,9 @@ public function tearDown(): void
5353
{
5454
parent::tearDown();
5555
Date::setDefaultLocale($this->locale);
56+
Date::setLenientParse(null);
5657
FrozenDate::setDefaultLocale($this->locale);
58+
FrozenDate::setLenientParse(null);
5759
date_default_timezone_set('UTC');
5860
}
5961

@@ -216,6 +218,25 @@ public function testParseDateTime($class)
216218
$this->assertSame('2015-10-13 00:00:00', $date->format('Y-m-d H:i:s'));
217219
}
218220

221+
/**
222+
* Tests disabling leniency when parsing locale format.
223+
*
224+
* @dataProvider classNameProvider
225+
* @return void
226+
*/
227+
public function testLenientParseDate($class)
228+
{
229+
$class::setDefaultLocale('pt_BR');
230+
231+
$class::setLenientParse(false);
232+
$date = $class::parseDate('04/21/2013');
233+
$this->assertSame(null, $date);
234+
235+
$class::setLenientParse(true);
236+
$date = $class::parseDate('04/21/2013');
237+
$this->assertSame('2014-09-04', $date->format('Y-m-d'));
238+
}
239+
219240
/**
220241
* provider for timeAgoInWords() tests
221242
*

tests/TestCase/I18n/TimeTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,12 @@ public function tearDown(): void
5454
Time::setDefaultLocale($this->locale);
5555
Time::resetToStringFormat();
5656
Time::setJsonEncodeFormat("yyyy-MM-dd'T'HH':'mm':'ssxxx");
57+
Time::setLenientParse(null);
5758

5859
FrozenTime::setDefaultLocale($this->locale);
5960
FrozenTime::resetToStringFormat();
6061
FrozenTime::setJsonEncodeFormat("yyyy-MM-dd'T'HH':'mm':'ssxxx");
62+
FrozenTime::setLenientParse(null);
6163

6264
date_default_timezone_set('UTC');
6365
I18n::setLocale(I18n::DEFAULT_LOCALE);
@@ -916,6 +918,25 @@ public function testParseTime($class)
916918
$this->assertNull($time);
917919
}
918920

921+
/**
922+
* Tests disabling leniency when parsing locale format.
923+
*
924+
* @dataProvider classNameProvider
925+
* @return void
926+
*/
927+
public function testLenientParseDate($class)
928+
{
929+
$class::setDefaultLocale('pt_BR');
930+
931+
$class::setLenientParse(false);
932+
$time = $class::parseDate('04/21/2013');
933+
$this->assertSame(null, $time);
934+
935+
$class::setLenientParse(true);
936+
$time = $class::parseDate('04/21/2013');
937+
$this->assertSame('2014-09-04', $time->format('Y-m-d'));
938+
}
939+
919940
/**
920941
* Tests that timeAgoInWords when using a russian locale does not break things
921942
*

0 commit comments

Comments
 (0)