php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #73405 MWrong Year when using IntlDateTimeFormatter
Submitted: 2016-10-27 17:06 UTC Modified: 2017-08-16 17:29 UTC
Votes:2
Avg. Score:3.5 ± 0.5
Reproduced:2 of 2 (100.0%)
Same Version:1 (50.0%)
Same OS:0 (0.0%)
From: f dot bosch at genkgo dot nl Assigned: cmb (profile)
Status: Not a bug Package: intl (PECL)
PHP Version: 7.0.12 OS: Ubuntu 16.04
Private report: No CVE-ID: None
 [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'.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-10-27 18:01 UTC] f dot bosch at genkgo dot nl
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.
 [2017-08-16 17:29 UTC] cmb@php.net
-Status: Open +Status: Not a bug -Assigned To: +Assigned To: cmb
 [2017-08-16 17:29 UTC] cmb@php.net
`Y` is supposed to show the year of "Week of Year". To get simply
the year, use 'y'. See also
<http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Field-Symbol-Table>.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Apr 20 04:01:28 2024 UTC