ZF-4657: Zend_Validate_Date('yyyy/MM/dd') returns FALSE but should return TRUE

Description

I understand what you are saying and that is why I insist on this... and posted a new example. I understand changer the timezone after the a Zend_Date object has been instanciated will result in problem as Zend_Date should be based on the default timezone.

In my environement, the default timezone is not set in the php.ini, so I set it ONCE :) in the bootstrap; then I have some problems with the date validator. So in my last example, I tried to reproduce the problem in a simple script (without MVC, forms and so on...). I set the default time zone in the begining of the script (and I won't change it) and I get different result if it is set to the US or China... Same thing if I change the default timezone explicitly in the php.ini and I do not set it in the script...

I get an unexpected result when I define the format 'yyyy/MM/dd' + timezone China but not with the default format.


Sorry it seems I don't have the right to add a comment... That's why I am editing the issue.

About the issue; If this behavior is normal, the documentation at http://framework.zend.com/manual/en/… is ambiguous or wrong then.

About the code I sent, even if I set the default timezone once then instantiate Zend_date

 
date_default_timezone_set("Asia/Taipei");

require_once 'Zend/Validate/Date.php';
$date = "1980/06/30";
$vali = new Zend_Validate_Date('yyyy/MM/dd');

print "\n".date_default_timezone_get()."\n";
$result = $vali->isValid($date);
var_dump($result);

outputs:

 
Asia/Taipei
bool(false)

In the documentation it is specified: "When creating Zend_Date instances, their timezone will automatically become the current default timezone!" So is there something I do not get? :)


This is another spooky example:

CODE:

 
require_once 'Zend/Validate/Date.php';
$date = "1980/06/30";
$vali = new Zend_Validate_Date('yyyy/MM/dd');

print "\n".date_default_timezone_get()."\n";
$result = $vali->isValid($date);
var_dump($result);

date_default_timezone_set("Asia/Taipei");
print "\n".date_default_timezone_get()."\n";
$result = $vali->isValid($date);
var_dump($result);

OUTPUT:

 
America/New_York
bool(true)

Asia/Taipei
bool(false)

For some specific dates, Zend_Validate_Date when defining a specific format does not return an expected result:

Expected behavior $date = "1980-06-30"; $vali = new Zend_Validate_Date(); // $vali->isValid($date) returns TRUE

UNexpected behavior !!! $date = "1980/06/30"; $vali = new Zend_Validate_Date('yyyy/MM/dd'); // $vali->isValid($date) returns FALSE but should be TRUE

Expected behavior $date = "1980/06/29"; $vali = new Zend_Validate_Date('yyyy/MM/dd'); // $vali->isValid($date) returns TRUE

This is a big problem for me as I use a date validator on a form for an order entry tool using this format of date (for China). So in this case the customer born the June 30th 1980 can not by the product we sell... I had to implement a custom validator to treat this issue.

Comments

I reworked you example:


require_once 'Zend/Validate/Date.php';

$date = "1980/06/30";
$vali = new Zend_Validate_Date('yyyy/MM/dd');
$result = $vali->isValid($date);  // returns FALSE but should be TRUE
var_dump($result);

But I get a boolean TRUE returned. I can't reproduce your problem.

Please add comments instead of changing the original issue

Your second code is a handling problem...

When you change the base timezone within your code, of course also the returned date object will differ. Changing the timezone can only work when you do this within the object and not within the configuration.

Sorry, but this is not a problem... see setTimezone() for proper changing of timezones for date objects.

When you set Zend_Date to the default timezone and then change this timezone (in php) afterwards, then the default timezone is different from before.

It is logically impossible that the date is not changed in this case. The thing is that you must not change the default timezone multiple times in your script. This is a no-no in every language !!

This note is only to remember users that they must set a default timezone in their bootstrap because in some php environments it is not set, and then unexpected results will occur.

This is a reproducable php bug which can not be solved by ZF.

Try the following code for reproduction:


date_default_timezone_set("Asia/Taipei");

print "\n1:".date('m.d.Y H:i:s', 331056000);
print "\n2:".date('m.d.Y H:i:s', 331142400);

As you see 1. returns 06.29.2008 00:00:00 But 2. returns 06.30.2008 01:00:00

As one day has 86400 seconds the initial values given to the two dates are correct.

There is one hour more than it should be. This date is no dst change so it seems to be a php bug. There is no way for ZF to fix such a deep bug.