Help with date validation

Hello,

New user here.

not sure if this is were I ask for help.

I have some date fields on my form and would like to prevent invalid date entries.

Current if the user enters a bad date or characters, the app crashes.

I am coming from a Codeigniter background.

Yii is great, cannot wait to learn it.

My todo list for my current project is:

  1. date validation.

  2. Master/Detail

  3. inline data entry

  4. pdf reports

Thanks for the help.

Frank

not exist class CDateValidator, but you can create it extending CValidator

and using like other validator

example




class CDateValidator extends CValidator {


	protected function validateAttribute($object,$attribute)

	{


           if(!$this->isEmpty($object->$attribute,true)){


           

           if (!is_date($object->$attribute)) { //is_date must be created

               

               $message=$this->message!==null?$this->message:Yii::t('yii','{attribute} is a bad date');

               $this->addError($object,$attribute,$message);

           }

           }

	}


}



in the model




public function rules()

	{

		return array(

                        array('date_field', 'CDateValidator'),

		);

	}



(no tested)

for

  1. Master/Detail

look http://www.yiiframework.com/doc/guide/form.table

and

http://www.yiiframework.com/doc/cookbook/19/

  1. inline data entry

look the guide, see the code generate for crud :unsure:

  1. pdf reports

look http://www.yiiframework.com/forum/index.php?/topic/6647-yii-with-generating-and-printing-reports-charts-etc/

I hope help you

greetings

Thank you so much.

I appreciate the help.

Yii looks like a great framework.

I remember Qiang Xue from many years ago when I did some Prado stuff (had to use .net).

Regards,

Frank

I created a class that you coded in folder components.

When I save a record, I get a blank page.

Any idea what is happening?

Thanks

ha ha, I told you: not tested

no idea, but is rare

a- happend when you input valid date or invalid date?

b- if you remove the validator, it happens?

If I remove the validator, the page displays ok.

I found an is_date function on this forum, but it does not stop users from entering characters.

This causes the app to throw an exception.

I tried just adding a is_date function that only returns true and the page hangs.

This is a show stopper for me on this project.

Thanks again.

Frank

I just found out that:

if (!is_date($value)) // Fails

if (!$this->is_date($value)) //works

However the user types 3/2/2009 and mysql fails because it wants 2009-3-2

I cannot believe this is so hard, as it is a common function.

I had similar problems a week ago… so I will show you how I solved it.

First the validation of the date(s)

here is myDateValidate.php that I put in protected/components:

  • I use strtotime so that you can enter words representing date in a date field, like: now, yesterday, +1 week, …



<?php

/**

* myDateValidator - validates that the entered text is a valid date

 */


class myDateValidator extends CValidator

{

    /**

     * Validates entered text to be a valid date

     */

    protected function validateAttribute($object,$attribute)

    {

        if(strtotime($object->{$attribute}))

        {

            $object->{$attribute}=date('d.m.Y',strtotime($object->{$attribute}));

        }

        else{

            $this->addError($object,$attribute,'Wrong date!');

        }

    }

}



in the model you need to set the rules for the date fields like:




public function rules()

        {

                return array(

                        //.. any other rules ...

                        array('date_field1', 'myDateValidator'),

                        array('date_field2', 'myDateValidator'),

                );

        }



Now for the conversion of the dates to/from the database, In my case for the display I use mm.dd.yyyy, mysql and postgresql uses ISO 9075 yyyy-mm-dd

here is myDateFormat.php that I put in protected/components:




<?php

/**

 * DateFormater - converts date from/to SQL database (ISO 9075=>"yyyy-mm-dd" to/from dd.mm.yyyy.

 */


class myDateFormat extends CActiveRecordBehavior

{

    //.. array of columns that have dates to be converted

    public $dateColumns = array();


    /**

     * Convert from $dateFormat to ISO 9075 dates before saving

     */

    public function beforeSave($event)

    {

        foreach( $this->dateColumns as $date )

        {

            $_dt = $this->Owner->{$date};

            if(ereg("([0-9]{1,2}).([0-9]{1,2}).([0-9]{4})", $_dt, $regs))

                $_dt = $regs[3]."-".$regs[2]."-".$regs[1];

            $this->Owner->{$date} = $_dt;

        }

        return parent::beforeSave($event);

    }


    /**

     * Converts ISO 9075 dates to dd.mm.yyyy after read from database

     */

    public function afterFind($event)

    {

        foreach( $this->dateColumns as $date )

        {

            $_dt = $this->Owner->{$date};

            if(ereg("([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})", $_dt, $regs))

                $_dt = $regs[3].".".$regs[2].".".$regs[1];

            $this->Owner->{$date} = $_dt;

        }

        return parent::afterFind($event);

    }

}



in the model you define behaviors and set what fields are date fields, like:




    public function behaviors(){

        return array(

            'myTimeStamp'=>array(

                //.. this is a behavior that adds current timestamp to a field

                'class'=>'application.components.myTimeStamp',

            ),

            'myDateFormat'=>array(

                'class'=>'application.components.myDateFormat',      //.. says that myDateFormat is in protected/components

                'dateColumns'=>array('date_field1','date_field2'),       //.. says that date_field1 and date_field2 are field of type date, and need to be converted

            ),

        );

    }



Thats it, hope it helps.

Thank you for taking the time to post this.

I am new to Yii and this is also a great example of solving problems.

Regards,

Frank

CTypeValidator will validate dates, per http://www.yiiframework.com/doc/guide/form.model

http://www.yiiframework.com/doc/api/CTypeValidator

So it seems that there is no specific need for a custom validator just to check a date.

What is concerning for me though, is that I can’t find any example of how to properly implement a “type” date validation rule, so this hint I’ve found is useless to me currently.

Has anyone else used the CTypeValidator for validating dates?

good news !!!

Ha, it’s good news, but how do we use it? :smiley:

I’m testing different implementations right now, keep getting fatal errors :-\

Found the validator cheat sheet, this explained it:

http://yii.googlecode.com/files/yii-1.1.0-validator-cheatsheet.pdf

So, you would specify a date format rule as such:




array('date_field', 'type', 'datetimeFormat'=>'MM/dd/yyyy'),



i’m use my CDateValidator because I come from 1.0.x

but the CtypeValidator is good (if work ;D )

What are the inputs that give an error?

what is the fatal error?

[edit]

look the class in

framework/validator/CTypeValidator

framework/utils/CDateTimeParser

maybe help you

Thanks, but my previous post referenced the proper way to use the validator :slight_smile:

As I didn’t have an example available, I was trying various different formats, each of which were incorrect and caused fatal errors.

Applying the proper format made it work though. :slight_smile:

Cheers

That didn’t quite work for me. This does:




array('date_field', 'type', 'type'=>'date', 'dateFormat'=>'MM/dd/yyyy'),



Thanks…

Looking at the code, you have it correct :slight_smile: I believe my example just resulted in no errors being tossed, hadn’t tested it yet (as I’m working on other areas currently)

Thanks!

Is there a simple way to validate a date as a string (like examples hereunder), but store it like a timestamp ?

If I use CTypeValidator to validate the date, then I can’t save the model with the date like a timestamp.

If I convert the string into a timestamp before to save, I will obtain a "must be an integer" in case of invalid date.

Did I miss something ?