|   | php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login | 
| 
  [2016-10-27 17:06 UTC] f dot bosch at genkgo dot nl
 Description:
------------
The formatter is one year of. I expect to see 2017, but I see 2016. It does not matter how I the change pattern, ddMMY or the pattern below will result in the same bug. This is also true for the timezone: Europe/Amsterdam or Europe/Paris. That does not matter.
However, changing the locale does matter. Only en_US gives the correct result, while nl_NL, fr_FR, en_US and de_DE are all resulting in one year of! And the problem does not occur a day later: if I change the DateTime object into 2017-01-02 it does work.
The bug is reproducible on my local system and remote systems. Is it me or have I just hit a famous millennium bug?
Test script:
---------------
$formatter = new IntlDateFormatter(
    'nl_NL',
    IntlDateFormatter::FULL,
    IntlDateFormatter::FULL,
    'Europe/Amsterdam',
    IntlDateFormatter::GREGORIAN,
    "dd'-'MM'-'Y"
);
$this->assertSame(
    '01-01-2017',
    $formatter->format(
        new DateTime('2017-01-01 12:00:00')
    )
);
Expected result:
----------------
The formatted date to be equal to '01-01-2017'.
Actual result:
--------------
The formatted date to be equal to '01-01-2016'.
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits             | |||||||||||||||||||||||||||||||||||||
|  Copyright © 2001-2025 The PHP Group All rights reserved. | Last updated: Fri Oct 31 18:00:01 2025 UTC | 
Using IntlCalendar instead of DateTime does not seem to help. The problem really comes from the locale with IntlDateFormatter. When I var_dump the internal values of the IntlCalendar become visible. That looks like follows. class IntlGregorianCalendar#33 (5) { public $valid => bool(true) public $type => string(9) "gregorian" public $timeZone => array(4) { 'valid' => bool(true) 'id' => string(16) "Europe/Amsterdam" 'rawOffset' => int(3600000) 'currentOffset' => int(7200000) } public $locale => string(5) "nl_NL" public $fields => array(23) { 'era' => int(1) 'year' => int(2017) 'month' => int(0) 'week of year' => int(52) 'week of month' => int(0) 'day of year' => int(1) 'day of month' => int(1) 'day of week' => int(1) 'day of week in month' => int(1) 'AM/PM' => int(1) 'hour' => int(7) 'hour of day' => int(19) 'minute' => int(42) 'second' => int(34) 'millisecond' => int(0) 'zone offset' => int(3600000) 'DST offset' => int(0) 'year for week of year' => int(2016) 'localized day of week' => int(7) 'extended year' => int(2017) 'julian day' => int(2457755) 'milliseconds in day' => int(70954000) 'is leap month' => int(0) } } That proves me, the problem really is inside the formatter.