4

I have a very simple table.

Evenementshistoriques table

I generated the files with

bin\cake bake all [tableName]

I now have a form where I can add/edit/remove entries.

Form

The problem is that if I put a date that's before 1st January 1600, I get an error saying that the date is invalid.

Error

I assume that the error comes from the validator.

Here are the validation rules :

 /**
 * Default validation rules.
 *
 * @param \Cake\Validation\Validator $validator Validator instance.
 * @return \Cake\Validation\Validator
 */
public function validationDefault(Validator $validator)
{
    $validator
        ->integer('id')
        ->allowEmpty('id', 'create');

    $validator
        ->date('debut_date')
        ->allowEmpty('debut_date');

    $validator
        ->date('fin_date')
        ->allowEmpty('fin_date');

    $validator
        ->allowEmpty('nom');

    $validator
        ->allowEmpty('description');

    return $validator;
}

I don't understand why this error happens. Could you help me please?

Thanks

  • 1
    Please be a little more specific about what exactly happens. Like where does the error actually stem from? CakePHP? The DBMS? And what _exactly_ does the error message say? If the error stems from CakePHP, then please mention where it is being shown, like is it a valiation error (ie it's shown in the form), or an exception? In case of a validation error, please show your validation and rules configuration. – ndm Jun 18 '16 at 12:15
  • Hi, thanks for your comment. I edited my post to be more specific. – William Gérald Blondel Jun 18 '16 at 12:22

1 Answers1

7

Not supported by validation

It looks like the validation simply doesn't allow years before 1600.

1[6-9]|[2-9]

https://github.com/cakephp/cakephp/blob/3.2.10/src/Validation/Validation.php#L404

I'm not sure about the reasoning behind this, maybe it is to cope with some DBMS's storage limitations, like SQL Servers 1/1/1753 minimum:

What is the significance of 1/1/1753 in SQL Server?

Consider alternative storage types, or even a different DBMS

Given that you want to store years before 1000, it's worth mentioning that officially, MySQLs DATE types supported range starts at 1000-01-01 (as mentioned by @user221931 in the comments). And while there seems to be unofficial support for years before 1000 (ie 0861-07-03 actually can be stored and worked with), this is probably not something that you want to rely on.

Possible solutions for this are a little offtopic here, and have been discussed on SO already, like

Does MySQL support historical date (like 1200)?

You can use a custom regex

Whether this is something that should maybe be changed in the core or not, in any case you could provide your own regex for the date validation to use, in order to accept pretty much any date you need, however you'd need to use add() as date() doesn't support custom regexes (might be worth an enhancement), like for example

->add('fin_date', [
    'rule' => ['date', null, '\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])']
])

That check may be too relaxed, but you should get the point.

You may want to open a ticket over at GitHub or visit IRC or Slack and ask the core team for clarification. Personally I think that supporting non-outdated/limited DBMS (given that this is actually the reason for that behavior) out of the box is something that could be worth an enhancement.

Community
  • 1
  • 1
ndm
  • 59,784
  • 9
  • 71
  • 110
  • Also MySQL can't store anything before 1000-01-01 in a `DATE` field, so trying to store 861-07-03 like in the posters example will fail too if using that db. – user221931 Jun 18 '16 at 13:23
  • @user221931 Ah, I've overlooked the OPs actual date. The docs say that the range starts at `1000-01-01`, but actually it seems that earlier dates do work, `0861-07-03` is being stored just fine, and date comparison and operations do work too. So there seems to be unofficial support for it at least, but that's of course nothing one should rely on. – ndm Jun 18 '16 at 13:43
  • Hi, Sorry for this late response, I forgot to reply to you. Thank you for all this information. What I did is that in the database I stored the normal date + 3000 years. I did that because I need to store negative years, down to -2000. Then, when I show the date on web pages, I just remove 3000 years from the date stored in the DB. – William Gérald Blondel Aug 05 '16 at 21:05