ソースを参照

Allow disabling lenient IntlDateFormatter parsing

Backport #14522
Cauan Cabral 5 年 前
コミット
c4660b20c4

+ 43 - 0
src/I18n/DateFormatTrait.php

@@ -35,6 +35,15 @@ trait DateFormatTrait
     public static $defaultLocale;
 
     /**
+     * Whether lenient parsing is enabled for IntlDateFormatter.
+     *
+     * Defaults to true which is the default for IntlDateFormatter.
+     *
+     * @var bool
+     */
+    protected static $lenientParsing = true;
+
+    /**
      * In-memory cache of date formatters
      *
      * @var \IntlDateFormatter[]
@@ -77,6 +86,8 @@ trait DateFormatTrait
     /**
      * Sets the default locale.
      *
+     * Set to null to use IntlDateFormatter default.
+     *
      * @param string|null $locale The default locale string to be used or null.
      * @return void
      */
@@ -86,6 +97,36 @@ trait DateFormatTrait
     }
 
     /**
+     * Gets whether locale format parsing is set to lenient.
+     *
+     * @return bool
+     */
+    public static function lenientParsingEnabled(): bool
+    {
+        return static::$lenientParsing;
+    }
+
+    /**
+     * Enables lenient parsing for locale formats.
+     *
+     * @return void
+     */
+    public static function enableLenientParsing(): void
+    {
+        static::$lenientParsing = true;
+    }
+
+    /**
+     * Enables lenient parsing for locale formats.
+     *
+     * @return void
+     */
+    public static function disableLenientParsing(): void
+    {
+        static::$lenientParsing = false;
+    }
+
+    /**
      * Returns a nicely formatted date string for this object.
      *
      * The format to be used is stored in the static property `Time::niceFormat`.
@@ -346,6 +387,8 @@ trait DateFormatTrait
             null,
             $pattern
         );
+        $formatter->setLenient(static::$lenientParsing);
+
         $time = $formatter->parse($time);
         if ($time !== false) {
             $result = new static('@' . $time);

+ 19 - 0
tests/TestCase/I18n/DateTest.php

@@ -215,6 +215,25 @@ class DateTest extends TestCase
     }
 
     /**
+     * Tests disabling leniency when parsing locale format.
+     *
+     * @dataProvider classNameProvider
+     * @return void
+     */
+    public function testLenientParseDate($class)
+    {
+        $class::setDefaultLocale('pt_BR');
+
+        $class::disableLenientParsing();
+        $date = $class::parseDate('04/21/2013');
+        $this->assertSame(null, $date);
+
+        $class::enableLenientParsing();
+        $date = $class::parseDate('04/21/2013');
+        $this->assertSame('2014-09-04', $date->format('Y-m-d'));
+    }
+
+    /**
      * provider for timeAgoInWords() tests
      *
      * @return array

+ 19 - 0
tests/TestCase/I18n/TimeTest.php

@@ -891,6 +891,25 @@ class TimeTest extends TestCase
     }
 
     /**
+     * Tests disabling leniency when parsing locale format.
+     *
+     * @dataProvider classNameProvider
+     * @return void
+     */
+    public function testLenientParseDate($class)
+    {
+        $class::setDefaultLocale('pt_BR');
+
+        $class::disableLenientParsing();
+        $time = $class::parseDate('04/21/2013');
+        $this->assertSame(null, $time);
+
+        $class::enableLenientParsing();
+        $time = $class::parseDate('04/21/2013');
+        $this->assertSame('2014-09-04', $time->format('Y-m-d'));
+    }
+
+    /**
      * Tests that timeAgoInWords when using a russian locale does not break things
      *
      * @dataProvider classNameProvider