Issues

ZF-5614: Autodetection on year fails for short date notation

Description

Zend_Date fails detecting the correct year using short date notation and setting the format to null or Zend_Date::DATE_MEDIUM.

$date = new Zend_Date('13.07.09', null, 'de_DE'); Zend_Debug::dump($date->getIso());

Returns: string(21) "9-07-13T00:00:00+0100"

The null problem could be easily fixed in Zend_Date using the attached patch, but it might be better to deal with it in Zend_Locale_Format::getDate (which would also solve the problem for Zend_Date::DATE_MEDIUM format).

Fixing it in Zend_Locale_Format::getDate might however introduce new side effects with dates prior to 1000 which are not left padded with zeros. Any ideas?

Regards, Maurice.

Comments

No, it does not fail the detection.

To clearify: When you give NULL you say that the date should be detected automatically. For Zend_Date it means that it expects a full notation and fills not given parts with 0. A year 9 is not a year 2009, so you will always get 9 returned in this case.

DATE_MEDIUM is defined in german language as dd.MM.yyyy. This means that the year part must be 4 digits long. As you did not gave 4 digits the year is automatically filled with 0 which means it detects 0009 which is equal to the year 9.

When you use the short notation you should also use DATE_SHORT instead of DATE_MEDIUM as the short notation is defined as dd.MM.yy and works as expected by returning 2009.

So this is not a bug. What you get depends on the given input and used format.

Hi Thomas, thanks for your reply.

If you say it's not a bug, then it's definitely a non-expected return value:

1) 9-07-13T00:00:00+0100 is not really 8601 compliant (is it?); it should be 0009-07-13T00:00:00+0100

2) If null means AUTO-DETECT, why doesn't it detect the short date correctly? I see that the short date has some drawbacks, because you have to guess the century, but I don't see a problem there (at least not for the next 50-60 years).

3) If you set DATE_MEDIUM as format (dd.MM.yyyy) and your date to detect is "13.07.09" I would still appreciate it being detected as 2009-07-13, because this is probably the date you'd like to have in 99.9 % of all cases. For those other 0.1 % you could still use "13.07.0009"...

To summarize: null actually means DATE_MEDIUM (Date.php line 2543), but I think the idea of filling 2 of the expected 4 digits with zeros is a strange and unexpected behavior. How to auto-detect dates in Zend then? I need something like that to validate form inputs.

To validate dates use Zend_Validate_Date and give the expected format as option. Zend_Date itself will not validate a date as it will automatically correct any false given input.

Yes, I'm using Zend_Validate_Date and yes, it says '13.07.09' is correct -- at least when I'm not specifying a format.


$validate_date = new Zend_Validate_Date(null, 'de_DE');
Zend_Debug::dump($validate_date->isValid('13.07.09'));
Zend_Debug::dump($validate_date->getErrors());

bool(true)

array(0) {
}

$validate_date = new Zend_Validate_Date(Zend_Date::DATE_SHORT, 'de_DE');
Zend_Debug::dump($validate_date->isValid('13.07.09'));
Zend_Debug::dump($validate_date->getErrors());

bool(false)

array(1) {
  [0] => string(15) "dateFalseFormat"
}

However I need that date in my database in ISO 8601. So I have to convert it using Zend_Date which "fails" giving me "9-07-13T00:00:00+0100" as I don't know if the user input is in SHORT, MEDIUM, ISO or whatever and I don't want to restrict the user so that only MEDIUM is valid.

Two things to mention:

First) Zend_Validate_Date can not handle constants of Zend_Date... Your second example does not work because you are giving as format "DATE_SHORT" which as you may already see will not match your given date. Within Zend_Validate_Date you have to specify your format manually.

A related feature enhancement is already planned.

Second) When you need to store a date in your database you MUST specify it. Each database uses a different format for ISO. Some need a T some not, some specify the timezone some not. There is actually no Standard-Iso Format for databases.

You have always to differ between input and output. Within this issue you throw together multiple components and handlings. Please stick to one description and not multiple handlings.

The issue itself with 2 digit short notation is accepted but it's solution does not solve your problem of validation not your problem of adding it to database.

Also to mention... even when you specify short notation, a long notation will be detected and used correct.

Improved detection of 2 digit year notation and fixed year formats with r13775