[Form] Date type does not accept years before 1902/after 2037 #5227

Closed
Irohane opened this Issue Aug 10, 2012 · 16 comments

Comments

Projects
None yet
9 participants

Irohane commented Aug 10, 2012

IntlDateFormatter have some issues in transformation of Date.

$fmt = new IntlDateFormatter('en_US', IntlDateFormatter::SHORT, IntlDateFormatter::SHORT, 'UTC', IntlDateFormatter::GREGORIAN, 'yyyy');

$value = new DateTime();
$value->setDate(1900, 1, 1);

var_dump($fmt->format($value));

Expected: string '1900'
Actual: boolean false

Since Date widget base on this formatter, by default it only display years in range 1902-2037.

Contributor

sstok commented Aug 10, 2012

What is your php version?

http://php.net/manual/en/intldateformatter.format.php
5.3.4 Support for providing DateTime objects to the value parameter was added.

Try this.

$fmt = new IntlDateFormatter('en_US', IntlDateFormatter::SHORT, IntlDateFormatter::SHORT, 'UTC', IntlDateFormatter::GREGORIAN, 'yyyy');

$value = new DateTime();
$value->setDate(1900, 1, 1);

var_dump($fmt->format($value->getTimestamp()));

Irohane commented Aug 10, 2012

Tested on 5.3.14 and 5.4.3 same results (false for years other than 1902-2037)

Hello! we are getting the same problem here.
This issue shows up in 32 bit machines, because the formatter changes the DateTime value to a integer timestamp to process it . Dates outside the epoch (1970) +- maxint will give you an error.
There are two ways to fix this:
1 - use a 64bit server.
2 - fix PHP IntlDateFormatter

We are going with 1- here, good luck!

aerthel commented Sep 10, 2012

A hacky workaround: to get the Date form type to accept dates past 2038 on 32-bit systems,
I modified the \vendor\symfony\src\Symfony\Component\Locale\Stub\DateFormat\FullTransformer.php file

At line 320 replace this

return $dateTime->getTimestamp();

with this

if($year >= 2038 && php_uname('m') === 'i586') return $dateTime->format('U');        
        else return $dateTime->getTimestamp();

This messes up the hour value of the DateTime, and only works with future dates (i didn't test years 1970 or below), but it's just what I needed.

Source: http://www.php.net/manual/en/datetime.gettimestamp.php#99598

Member

stof commented Oct 22, 2012

Does this issue occurs when using the intl extension or the stub intl implementation ?

Intl extension, 32 bit Ubuntu, installed from ppa

PHP 5.3.15-0ppa1p with Suhosin-Patch (cli) (built: Aug 4 2012 03:33:59)
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies
with Zend Debugger v5.3, Copyright (c) 1999-2010, by Zend Technologies

On Mon, Oct 22, 2012 at 3:00 PM, Christophe Coevoet <
notifications@github.com> wrote:

Does this issue occurs when using the intl extension or the stub intl
implementation ?


Reply to this email directly or view it on GitHubhttps://github.com/symfony/symfony/issues/5227#issuecomment-9671768.

Contributor

webmozart commented Nov 9, 2012

I think that this needs to be resolved in PHP. Have you reported a bug there [1]?

In ICU, the dealing of years prior to 1902 seems to work judging from this ticket [2]. But we will know more when the PHP guys respond to the bug report.

[1] https://bugs.php.net
[2] http://icu-project.org/trac/ticket/5513

Member

wouterj commented Jan 29, 2013

I have this issue too, using Wamp with PHP5.4.3 and intl enabled. Is there any information on how to fix this?

LouWii commented Feb 11, 2013

Just had to modify the \vendor\symfony\src\Symfony\Component\Locale\Stub\DateFormat\FullTransformer.php file. I really don't like to modify a Core Symfony file but I had to...

Any news about how to fix that without modifying this symfo file ?

Contributor

webmozart commented Feb 22, 2013

Again, has anyone reported a bug to php.net?

aerthel commented Feb 22, 2013

I'd like to provide some more insight into this issue.

I did a little boundary value analysis, comparing the output of the current function getTimestamp() in the FullTransformer file, and the format("U") function:

DateTime    getTimestamp()   format("U")
0001-12-31           false   62104130234
1901-12-13           false   -2147541434
1901-12-14     -2147455034   -2147455034
1985-12-17       503636400     503636400

2012-1-19       1326942000    1326942000
2038-1-19       2147482800    2147482800
2038-1-20            false    2147569200
9999-1-21            false  253372503600

This leads me to believe that $date->format("U") is a more reliable function and should be used instead $date->getTimestamp() on the FullTransformer.php file.
If this is not the expected behavior of the getTimestamp() function, i agree a bug should be reported to php.net, however i'm not sure if this is the case or not.

Tested with PHP 5.3.2-1ubuntu4.18 with Suhosin-Patch (cli) (built: Sep 12 2012 19:33:42) on a 32 bit machine. Hope this helps on getting this issue fixed :)

Contributor

webmozart commented Feb 25, 2013

@aerthel The issue is not (primarily) the FullTransformer file, but PHP's implementation of IntlDateTransformer. FullTransformer is just a stub for the case that the intl extension is not available.

Contributor

webmozart commented Feb 25, 2013

Thank you for the test results though!

Contributor

webmozart commented Feb 25, 2013

This is a limitation in PHP itself:

The valid range of a timestamp is typically from Fri, 13 Dec 1901 20:45:54 GMT to Tue, 19 Jan 2038 03:14:07 GMT. (These are the dates that correspond to the minimum and maximum values for a 32-bit signed integer). However, before PHP 5.1.0 this range was limited from 01-01-1970 to 19-01-2038 on some systems (e.g. Windows).

Contributor

mvrhov commented Feb 25, 2013

64bit version of PHP solves this problem as it does many other when dealing with large integers:

php > $d = new DateTime('0001-12-31');
php > echo $d->getTimestamp();
-62104150800
php > echo PHP_INT_MAX;
9223372036854775807
php >

@webmozart webmozart referenced this issue in symfony/symfony-docs Feb 25, 2013

Closed

[Form] Document DateType limitations #2266

Contributor

webmozart commented Feb 25, 2013

Fortunately, this issue seems to be limited to (a) 32bit systems and (b1) the option widget being set to 'single_text' or (b2) the option input being set to 'timestamp'. For 64bit systems and other values of the above settings, date outside this range work fine.

Marked as documentation issue. See symfony/symfony-docs#2266

@webmozart webmozart closed this Feb 25, 2013

fabpot added a commit that referenced this issue Nov 28, 2013

bug #9314 [Form] Fix DateType for 32bits computers. (WedgeSama)
This PR was squashed before being merged into the 2.2 branch (closes #9314).

Discussion
----------

[Form] Fix DateType for 32bits computers.

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #5227,#5554
| License       | MIT
| Doc PR        | -

Fix an issue due to 32bits machines, date can be only between 1902-2037.
Simply not add date if false. Can be good to add this to 2.3 and master too.

Commits
-------

b80fb43 [Form] Fix DateType for 32bits computers.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment