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
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: f dot bosch at genkgo dot nl
New email:
PHP Version: OS:

 

 [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

Pull Requests

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-2025 The PHP Group
All rights reserved.
Last updated: Thu Mar 13 21:01:32 2025 UTC