mirror of
				https://github.com/yiisoft/yii2.git
				synced 2025-11-04 14:46:19 +08:00 
			
		
		
		
	date formatter fall back to PHP impl. to solve Y2K38 issue
formatting date and time values for years >=2038 or <=1901 is now possible also with intl extension is installed. 32bit systems will fall back to the PHP implementation because intl uses a 32bit UNIX timestamp internally. On a 64bit system the intl formatter is used in all cases if installed. fixes #5577
This commit is contained in:
		@ -51,6 +51,10 @@ echo Yii::$app->formatter->asDate('2014-01-01'); // output: 1 января 2014
 | 
			
		||||
> [PHP intl extension](http://php.net/manual/en/book.intl.php) is installed or not. So to ensure your website works with the same output
 | 
			
		||||
> in all environments it is recommended to install the PHP intl extension in all environments and verify that the version of the ICU library
 | 
			
		||||
> is the same. See also: [Setting up your PHP environment for internationalization](tutorial-i18n.md#setup-environment).
 | 
			
		||||
>
 | 
			
		||||
> Note also that even if the intl extension is installed, formatting date and time values for years >=2038 or <=1901
 | 
			
		||||
> on 32bit systems will fall back to the PHP implementation, which does not provide localized month and day names,
 | 
			
		||||
> because intl uses a 32bit UNIX timestamp internally. On a 64bit system the intl formatter is used in all cases if installed.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Configuring the formatter <a name="configuring-format"></a>
 | 
			
		||||
 | 
			
		||||
@ -4,6 +4,7 @@ Yii Framework 2 Change Log
 | 
			
		||||
2.0.2 under development
 | 
			
		||||
-----------------------
 | 
			
		||||
 | 
			
		||||
- Bug #5577: formatting date and time values for years >=2038 or <=1901 on 32bit systems will not use intl extension but fall back to the PHP implementation (cebe)
 | 
			
		||||
- Bug #6080: Oracle DB schema did not load column types correctly (wenbin1989)
 | 
			
		||||
- Bug #6404: advanced application template `Alert` widget was generating duplicate IDs in case of multiple flashes (SDKiller)
 | 
			
		||||
- Bug #6557: Link URLs generated by `yii\widgets\Menu` are not encoded (qiangxue)
 | 
			
		||||
 | 
			
		||||
@ -35,6 +35,9 @@ use yii\helpers\Html;
 | 
			
		||||
 * the [PHP intl extension](http://php.net/manual/en/book.intl.php) has to be installed.
 | 
			
		||||
 * Most of the methods however work also if the PHP intl extension is not installed by providing
 | 
			
		||||
 * a fallback implementation. Without intl month and day names are in English only.
 | 
			
		||||
 * Note that even if the intl extension is installed, formatting date and time values for years >=2038 or <=1901
 | 
			
		||||
 * on 32bit systems will fall back to the PHP implementation because intl uses a 32bit UNIX timestamp internally.
 | 
			
		||||
 * On a 64bit system the intl formatter is used in all cases if installed.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Qiang Xue <qiang.xue@gmail.com>
 | 
			
		||||
 * @author Enrica Ruedin <e.ruedin@guggach.com>
 | 
			
		||||
@ -543,7 +546,9 @@ class Formatter extends Component
 | 
			
		||||
            return $this->nullDisplay;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($this->_intlLoaded) {
 | 
			
		||||
        // intl does not work with dates >=2038 or <=1901 on 32bit machines, fall back to PHP
 | 
			
		||||
        $year = $timestamp->format('Y');
 | 
			
		||||
        if ($this->_intlLoaded && !(PHP_INT_SIZE == 4 && ($year <= 1901 || $year >= 2038))) {
 | 
			
		||||
            if (strncmp($format, 'php:', 4) === 0) {
 | 
			
		||||
                $format = FormatConverter::convertDatePhpToIcu(substr($format, 4));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@ -182,9 +182,7 @@ class FormatterDateTest extends TestCase
 | 
			
		||||
 | 
			
		||||
    public function testIntlDateRangeLow()
 | 
			
		||||
    {
 | 
			
		||||
        if (PHP_INT_SIZE == 4) { // 32bit systems
 | 
			
		||||
            $this->markTestSkipped('intl does not support high date ranges on 32bit systems.');
 | 
			
		||||
        }
 | 
			
		||||
        // intl does not support high date ranges on 32bit systems, the implementation uses a fallback to PHP formatter
 | 
			
		||||
        $this->testDateRangeLow();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -196,13 +194,12 @@ class FormatterDateTest extends TestCase
 | 
			
		||||
    {
 | 
			
		||||
        $this->assertSame('12-08-1922', $this->formatter->asDate('1922-08-12', 'dd-MM-yyyy'));
 | 
			
		||||
        $this->assertSame('14-01-1732', $this->formatter->asDate('1732-01-14', 'dd-MM-yyyy'));
 | 
			
		||||
        $this->assertSame('01-01-0000', $this->formatter->asDate('0000-01-01', 'dd-MM-yyyy'));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testIntlDateRangeHigh()
 | 
			
		||||
    {
 | 
			
		||||
        if (PHP_INT_SIZE == 4) { // 32bit systems
 | 
			
		||||
            $this->markTestSkipped('intl does not support high date ranges on 32bit systems.');
 | 
			
		||||
        }
 | 
			
		||||
        // intl does not support high date ranges on 32bit systems, the implementation uses a fallback to PHP formatter
 | 
			
		||||
        $this->testDateRangeHigh();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -214,6 +211,7 @@ class FormatterDateTest extends TestCase
 | 
			
		||||
    {
 | 
			
		||||
        $this->assertSame('17-12-2048', $this->formatter->asDate('2048-12-17', 'dd-MM-yyyy'));
 | 
			
		||||
        $this->assertSame('17-12-3048', $this->formatter->asDate('3048-12-17', 'dd-MM-yyyy'));
 | 
			
		||||
        $this->assertSame('31-12-9999', $this->formatter->asDate('9999-12-31', 'dd-MM-yyyy'));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function buildDateSubIntervals($referenceDate, $intervals)
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user