Search code examples
phpyii2yii2-basic-appyii2-modelyii2-validation

Yii2 date comparison not working inside rules()


I have a form, and a user have to enter a date of beginning and a date of ending.

I'm using the compare attribute inside the rules method because the user can't enter a date of ending which is before the date of beginning.

Here's my rules method inside the form's model :

['dateFinTR', 'date', 'format' => 'php: d/m/Y'],
['dateFinTR', 'compare', 'compareAttribute' => 'dateDebutTR', 'operator' => '>=', 'skipOnEmpty' => true,]

The problem is if a user enter a date of beginning as 2016-05-18 and a date of ending of 2016-04-17, an error message is shown and the user can't submit the form. But if the user enter a date of beginning of 2016-05-18 and a date of ending of 2016-04-23 there is no error and the user can't submit the form. In fact only the day is compared with this rule.

EDIT According to this link: Yii2 Date compare validation, I've created a custom validation method but I'm using european format so I think the strtotime method is not wirking good. Here's my validateDates method :

public function validateDates()
{
    if (strtotime($this->dateFinTR) <= strtotime($this->dateDebutTR))
    {
        $this->addError('dateFinTR', 'Veuillez saisir une date de fin se trouvant avant la date de début');
    }
}

And here's the call of this method :

['dateFinTR', 'validateDates', 'skipOnEmpty' => true],

Solution

  • It is a common date formatting/converting problem, not really specific to Yii.

    You could simply try to use DateTime::createFromFormat(), e.g. :

    public function validateDates()
    {
        $date1 = \DateTime::createFromFormat('d/m/Y', $this->dateDebutTR);
        $date2 = \DateTime::createFromFormat('d/m/Y', $this->dateFinTR);
        if ($date2<=$date1) {
            $this->addError('dateFinTR', 'error message');
        }
    }
    

    But it should be better, in most cases, to store dates in your database with the right format (DATE with MySQL for example), and only convert them for display.