15

I'm using codeigniter with PHP. I'm using following form,

<?php
    echo form_open('/register/create_new', $form_params);
?>

DOB: <input type="text" id="dob" name="reg[dob]">
     <input type="submit" value="Create Account" />
</form>

here, #dob is in dd-mm-yyyy format.

my validation code is,

array(
  'field' => 'reg[dob]',
  'label' => 'DOB',
  'rules' => 'required'
)

How can i set the rules for correct date validation?

2
  • If possible - consider using separate dropdown menus for day month year . Less errors for your users, especially with the month and day mixups that can happen. Commented Jan 16, 2013 at 16:26
  • 1
    @cartalot but, im using jquery datepicker Commented Jan 17, 2013 at 5:08

10 Answers 10

22

I have a pretty clean solution for this. You can extend codeigniters form validation library.

Do this by putting a MY_Form_validation.php file in your application/libraries folder. This file should look like this:

class MY_Form_validation extends CI_Form_validation {

    public function __construct($rules = array()) {
        parent::__construct($rules);
    }


    public function valid_date($date) {
        $d = DateTime::createFromFormat('Y-m-d', $date);
        return $d && $d->format('Y-m-d') === $date;
    }
}

To add the error message, you go to your application/language/ folder and open the form_validation_lang.php file. Add an entry to the $lang array at the end of the file, like so:

$lang['form_validation_valid_date'] = 'The field {field} is not a valid date';

Note that the key here must be the same as the function name (valid_date).

Then in your controller you use this as any other form validation function like for example 'required'

$this->form_validation->set_rules('date','Date','trim|required|valid_date');
Sign up to request clarification or add additional context in comments.

6 Comments

This is a very elegant solution, and I would like to recommend an additional change to allow better customisation. Adding a parameter for the date format: function valid_date($date, $format = 'Y-m-d') and referencing it in the function. You can pass this parameter in the validation rules like: 'trim|required|valid_date[d-m-y]' Then the lang file can use {param} to specify the expected format on error.
plus one for nice standard way.....need to add format parameter aswell.
This is by far the best answer!
This should definitely be the accepted answer. Nice, elegant, standard.
|
22

You can take use of CodeIgniters callback functions by creating a date_valid() function that checks if the given date is valid. If you want to use a method instead of a function, you should add callback_ prefix to the rule name.

And to check if it is valid, you could use PHP's checkdate function .

array(
  'field' => 'reg[dob]',
  'label' => 'DOB',
  'rules' => 'required|date_valid'
)

function date_valid($date){
    $day = (int) substr($date, 0, 2);
    $month = (int) substr($date, 3, 2);
    $year = (int) substr($date, 6, 4);
    return checkdate($month, $day, $year);
}

2 Comments

Using proper date functions is the way to go. Nice answer.
I think this is the way to go too. One thing, the name of the function has to be without "callback". So the right way would be> function date_valid($date){
9

you can do it with regex

$this->form_validation->set_rules('reg[dob]', 'Date of birth', 'regex_match[(0[1-9]|1[0-9]|2[0-9]|3(0|1))-(0[1-9]|1[0-2])-\d{4}]'); 

5 Comments

It's impossible to implement reliable date validation with regular expressions. Yours is actually quite good but, for instance, it claims that 29-02-2000 is not valid.
@ÁlvaroG.Vicario i think its also possible with 'regex'
Yeah, right, if you have the patience you can probably hard-code all the exceptions (including missing days due to transition to Gregorian calendar) but you know what I mean: regular expressions are not the best tool.
This regex format doesn't work. I had to enclose the pattern with /.../. Also, I can't get this pattern to work. regex_match[/\d{4}-\d{2}-\d{2}/] seems to work, but not regex_match[/\d{4}-(0[1-9]|1[0-2])-\d{2}/]. I'm gonna stick to the callback method.
2

I know this is old, but I just encountered the same issue. I like the answer Winks provided, but found that the code did not work. I modified it to this:

  public function your_form_handler($date)
  {
    // ....
    $this->form_validation->set_rules('date', 'Date', 'required|callback_date_valid');
    // ....
  }

  /**
   * Validate dd/mm/yyyy
   */
  public function date_valid($date)
  {
    $parts = explode("/", $date);
    if (count($parts) == 3) {      
      if (checkdate($parts[1], $parts[0], $parts[2]))
      {
        return TRUE;
      }
    }
    $this->form_validation->set_message('date_valid', 'The Date field must be mm/dd/yyyy');
    return false;
  }

1 Comment

I found itz useful. But this also validates 21/07/1yyy. ie, one digit year also validated.
2

There is no builtin date validation in Codeigniter form_validation Library, but you can use its callback to call a function and validate the date using PHP's own capabilities.

With DateTime you can make the shortest date&time validator for all formats.

function validateDate($date, $format = 'Y-m-d H:i:s')
{
    $d = DateTime::createFromFormat($format, $date);
    return $d && $d->format($format) == $date;
}

var_dump(validateDate('2012-02-28 12:12:12')); # true
var_dump(validateDate('2012-02-30 12:12:12')); # false
var_dump(validateDate('2012-02-28', 'Y-m-d')); # true
var_dump(validateDate('28/02/2012', 'd/m/Y')); # true
var_dump(validateDate('30/02/2012', 'd/m/Y')); # false
var_dump(validateDate('14:50', 'H:i')); # true
var_dump(validateDate('14:77', 'H:i')); # false
var_dump(validateDate(14, 'H')); # true
var_dump(validateDate('14', 'H')); # true

var_dump(validateDate('2012-02-28T12:12:12+02:00', 'Y-m-d\TH:i:sP')); # true
# or
var_dump(validateDate('2012-02-28T12:12:12+02:00', DateTime::ATOM)); # true

var_dump(validateDate('Tue, 28 Feb 2012 12:12:12 +0200', 'D, d M Y H:i:s O')); # true
# or
var_dump(validateDate('Tue, 28 Feb 2012 12:12:12 +0200', DateTime::RSS)); # true
var_dump(validateDate('Tue, 27 Feb 2012 12:12:12 +0200', DateTime::RSS)); # false

function was copied from this answer or php.net

Comments

1

Try this one out...i think it's more simple.

$this->form_validation->set_rules('date', 'Date', 'trim|required|callback_checkDateFormat');

function checkDateFormat($date) {
        $d = DateTime::createFromFormat('Y-m-d', $date);
        if(($d && $d->format('Y-m-d') === $date) === FALSE){
            $this->form_validation->set_message('checkDateFormat', ''.$date.' is not a valid date format.');
            return FALSE;
        }else{
            return TRUE;
        }
}

Comments

0

I like the answer tmsimont provided, but found that the code did not work if non numeric values enterd. Modified code is given below:

/**
    * Validate dd/mm/yyyy
    */
    public function date_valid(){
        $date=$this->input->post('dob');
        $parts = explode("/", $date);
        if (count($parts) == 3) {     
            if (is_numeric($parts[2])) {  
                if (is_numeric($parts[0])) {
                    if (is_numeric($parts[1])) {    
                        if (checkdate($parts[1], $parts[0], $parts[2])){
                            return TRUE;
                        }
                    }
                }
            }
        }

        $this->form_validation->set_message('date_valid', 'The Date field must be mm/dd/yyyy');
        return false;
    }

Comments

0

The actual Regex for Codeigniter Date validation :

$this->form_validation->set_rules('reg[dob]','Date of birth',array('regex_match[/^((0[1-9]|[12][0-9]|3[01])[- \/.](0[1-9]|1[012])[- \/.](19|20)\d\d)$/]'));

I am using same expression for format dd-mm-yyyy and dd/mm/yyyy

No Warnings and errors :-)

Comments

0

I've written this custom validator for ci3 - validates the d/m/Y H:i format - you can easily change that.

$this->form_validation->set_rules("start_date", "Start Date", 'trim|callback__check_date_valid');


   public function _check_date_valid($date){

    $this->form_validation->set_message('_check_date_valid', "Please enter a valid date");
    $d = DateTime::createFromFormat('d/m/Y H:i', $date);

    if($d && $d->format('d/m/Y H:i') === $date || $date == ''){
        return true;
    }else{

        return false;
    }

}

1 Comment

Unless you're good with regex - this is safer and allows you to explicitly set the php date format to validate against.
0

According to iamyojimbo answer,

    $date = [
        '28.02.2012', // true
        '28/02/2012', // true
        '28-02-2012', // true
        '28 02 2012', // true
        '28 02 1812', // false
    ];

    $pattern = '/^(0[1-9]|[12][0-9]|3[01])[\.\/\-\ ](0[1-9]|1[012])[\.\/\-\ ](19|20)\d\d$/';

    foreach ($date as $subject) {
        print_r(
            preg_match(
                $pattern,
                $subject
            )
        );
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.