Zend Framework

Incorrect month definition using 'setDate' method

Details

  • Type: Bug Bug
  • Status: Resolved Resolved
  • Priority: Major Major
  • Resolution: Fixed
  • Affects Version/s: 1.5.2
  • Fix Version/s: 1.6.0
  • Component/s: Zend_Date
  • Labels:
    None

Description

I'm using setDate method to parse date to get unix timestamp as follows:
$date->setDate('6/1/2008', 'M/d/Y');
It works fine on some linux platforms but has a bug on others.
If I want to parse a date with month set to one which has number of days less than 31 it adds 1 to month number.
Say, if I parse '2/10/2008', '4/15/2008', '6/22/2008' it always returns timestamp with month set to 3, 5, 7 accordingly.
I've got a solution for this bug. I've made a little modification to 'Zend_Date' class, '_date' method.
There are three lines which set the date in three steps as follows:
$date->set($parsed['year'], Zend_Date::YEAR);
$date->set($parsed['month'], Zend_Date::MONTH);
$date->set($parsed['day'], Zend_Date::DAY);

The order of the last two lines should be changed to fix the bug as follows:
$date->set($parsed['year'], Zend_Date::YEAR);
$date->set($parsed['day'], Zend_Date::DAY);
$date->set($parsed['month'], Zend_Date::MONTH);

The first line sets date to the defined year, month 12 and day 31. The second sets date to the defined day and the last sets date to the defined month.
We cannot set month before day because when we set year it sets default day number to 31. Then if we set month which has 30 days (April, June...) it switches month to the next one (May, July...) and day number to 1.

Please fix this in official release.

Activity

Hide
Thomas Weidner added a comment -

Where is your problem ?
Can you give us a example with code which shows the problem ? What you get, what you expected, the release, php version, os and so on...
Why should setting the 1.June respond in such a problem as you described ?

But: When you set 31.February you will ALWAYS get the 2 or 3rd May.
This is no failure but expected behaviour and documented within the manual.
I believe there is an option where you can switch off the overlapping for months.

When you set a impossible date, Zend_Date will always automatically correct this.
As your change introduces problems with existing code it will not be added to trunk.

What would you expect to get returned when you set a 32.Feburary ??

Show
Thomas Weidner added a comment - Where is your problem ? Can you give us a example with code which shows the problem ? What you get, what you expected, the release, php version, os and so on... Why should setting the 1.June respond in such a problem as you described ? But: When you set 31.February you will ALWAYS get the 2 or 3rd May. This is no failure but expected behaviour and documented within the manual. I believe there is an option where you can switch off the overlapping for months. When you set a impossible date, Zend_Date will always automatically correct this. As your change introduces problems with existing code it will not be added to trunk. What would you expect to get returned when you set a 32.Feburary ??
Hide
Art Pro added a comment -

PHP Version 5.2.4, Zend Framework 1.0.2 and 1.5.2 (both), Linux 2.6.24.5-g-r17 #1 SMP
Exact test case is
$date = new Zend_Date();
$date->setDate('6/1/2008', 'M/d/Y');
print $date->toString('M/d/Y');
// retruns "7/1/2008" and same problem with other months which have less than 31 days

Show
Art Pro added a comment - PHP Version 5.2.4, Zend Framework 1.0.2 and 1.5.2 (both), Linux 2.6.24.5-g-r17 #1 SMP Exact test case is $date = new Zend_Date(); $date->setDate('6/1/2008', 'M/d/Y'); print $date->toString('M/d/Y'); // retruns "7/1/2008" and same problem with other months which have less than 31 days
Hide
Thomas Weidner added a comment -

I am not able to reproduce your behaviour with trunk.
When you are willing to test I would recommend that you

  • install the trunk release (9600 or higher)
  • run this example:
    $date = new Zend_Date();
    print "\n".$date->getIso();
    $date->setDate('6/1/2008', 'M/d/Y');
    print "\n".$date->getIso();
  • when it fails please return the output
  • additionally run and return the output of the following:
    print_r (Zend_Locale_Format::getDate('6/1/2008', array('date_format' => 'M/d/Y', 'format_type' => 'iso'));
Show
Thomas Weidner added a comment - I am not able to reproduce your behaviour with trunk. When you are willing to test I would recommend that you
  • install the trunk release (9600 or higher)
  • run this example:
    $date = new Zend_Date();
    print "\n".$date->getIso();
    $date->setDate('6/1/2008', 'M/d/Y');
    print "\n".$date->getIso();
  • when it fails please return the output
  • additionally run and return the output of the following:
    print_r (Zend_Locale_Format::getDate('6/1/2008', array('date_format' => 'M/d/Y', 'format_type' => 'iso'));
Hide
Art Pro added a comment -

Updated to revision 9605. The problem is still there.
Here is my code:

<pre>
<?
require_once('./Zend/Date.php');

$date = new Zend_Date();
print "\n".$date->getIso();
$date->setDate('6/1/2008', 'M/d/Y');
print "\n".$date->getIso();
print "\n\n";
print_r(Zend_Locale_Format::getDate('6/1/2008', array('date_format' => 'M/d/Y', 'format_type' => 'iso')));
?>

And here is return:

2008-06-04T08:27:02-05:00
2008-07-01T08:27:02-05:00

Array
(
    [date_format] => M/d/Y
    [locale] => 
    [month] => 6
    [day] => 1
    [year] => 2008
)
Show
Art Pro added a comment - Updated to revision 9605. The problem is still there. Here is my code:
<pre>
<?
require_once('./Zend/Date.php');

$date = new Zend_Date();
print "\n".$date->getIso();
$date->setDate('6/1/2008', 'M/d/Y');
print "\n".$date->getIso();
print "\n\n";
print_r(Zend_Locale_Format::getDate('6/1/2008', array('date_format' => 'M/d/Y', 'format_type' => 'iso')));
?>
And here is return:
2008-06-04T08:27:02-05:00
2008-07-01T08:27:02-05:00

Array
(
    [date_format] => M/d/Y
    [locale] => 
    [month] => 6
    [day] => 1
    [year] => 2008
)
Hide
Thomas Weidner added a comment -

Ok... now it gets durty

Date.php:
line 2924: add "print "\n".$date->getIso();" below.
Also below 2925, 2926, 2927 and 2928

Also output me your locale $locale from line 2924.

Show
Thomas Weidner added a comment - Ok... now it gets durty Date.php: line 2924: add "print "\n".$date->getIso();" below. Also below 2925, 2926, 2927 and 2928 Also output me your locale $locale from line 2924.
Hide
Art Pro added a comment -

Output is now

2008-06-04T09:02:33-05:00
1969-12-31T18:00:00-06:00
$locale = en_US
2008-12-31T18:00:00-06:00
2008-07-01T18:00:00-05:00
2008-07-01T18:00:00-05:00
Tuesday, July 1, 2008
2008-07-01T09:02:33-05:00

Array
(
    [date_format] => M/d/Y
    [locale] => 
    [month] => 6
    [day] => 1
    [year] => 2008
)
Show
Art Pro added a comment - Output is now
2008-06-04T09:02:33-05:00
1969-12-31T18:00:00-06:00
$locale = en_US
2008-12-31T18:00:00-06:00
2008-07-01T18:00:00-05:00
2008-07-01T18:00:00-05:00
Tuesday, July 1, 2008
2008-07-01T09:02:33-05:00

Array
(
    [date_format] => M/d/Y
    [locale] => 
    [month] => 6
    [day] => 1
    [year] => 2008
)
Hide
Thomas Weidner added a comment -

Ok... problem found.

Please change line 2924 so it looks like this:

$date = new self(0, self::TIMESTAMP, $locale);
            $date->setTimezone('UTC');

This should fix your problem.
Please test it and give me the result.

Thanks...

Show
Thomas Weidner added a comment - Ok... problem found. Please change line 2924 so it looks like this:
$date = new self(0, self::TIMESTAMP, $locale);
            $date->setTimezone('UTC');
This should fix your problem. Please test it and give me the result. Thanks...
Hide
Art Pro added a comment -

Yes, this fixes the bug:

2008-06-05T04:18:35-05:00
1970-01-01T00:00:00+00:00
$locale = en_US
2008-01-01T00:00:00+00:00
2008-06-01T00:00:00+00:00
2008-06-01T00:00:00+00:00
Sunday, June 1, 2008
2008-06-01T04:18:35-05:00

Array
(
    [date_format] => M/d/Y
    [locale] => 
    [month] => 6
    [day] => 1
    [year] => 2008
)
Show
Art Pro added a comment - Yes, this fixes the bug:
2008-06-05T04:18:35-05:00
1970-01-01T00:00:00+00:00
$locale = en_US
2008-01-01T00:00:00+00:00
2008-06-01T00:00:00+00:00
2008-06-01T00:00:00+00:00
Sunday, June 1, 2008
2008-06-01T04:18:35-05:00

Array
(
    [date_format] => M/d/Y
    [locale] => 
    [month] => 6
    [day] => 1
    [year] => 2008
)
Hide
Thomas Weidner added a comment -

The fix has been added with r9612

Show
Thomas Weidner added a comment - The fix has been added with r9612
Hide
Wil Sinclair added a comment -

Updating for the 1.6.0 release.

Show
Wil Sinclair added a comment - Updating for the 1.6.0 release.

People

Vote (0)
Watch (0)

Dates

  • Created:
    Updated:
    Resolved:

Time Tracking

Estimated:
Not Specified
Original Estimate - Not Specified
Remaining:
0m
Remaining Estimate - 0 minutes
Logged:
3h
Time Spent - 3 hours