PHP Unconference Europe 2015

checkdate

(PHP 4, PHP 5)

checkdateValidate a Gregorian date

Description

bool checkdate ( int $month , int $day , int $year )

Checks the validity of the date formed by the arguments. A date is considered valid if each parameter is properly defined.

Parameters

month

The month is between 1 and 12 inclusive.

day

The day is within the allowed number of days for the given month. Leap years are taken into consideration.

year

The year is between 1 and 32767 inclusive.

Return Values

Returns TRUE if the date given is valid; otherwise returns FALSE.

Examples

Example #1 checkdate() example

<?php
var_dump
(checkdate(12312000));
var_dump(checkdate(2292001));
?>

The above example will output:

bool(true)
bool(false)

See Also

  • mktime() - Get Unix timestamp for a date
  • strtotime() - Parse about any English textual datetime description into a Unix timestamp

add a note add a note

User Contributed Notes 13 notes

up
119
glavic at gmail dot com
1 year ago
With DateTime you can make the shortest date&time validator for all formats.

<?php

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
# ...
up
1
Bas
8 months ago
And here is a version which will work for PHP 5.2 also.

function ValidateDate($date, $format = 'Y-m-d H:i:s') {
    $version = explode('.', phpversion());
    if (((int) $version[0] >= 5 && (int) $version[1] >= 2 && (int) $version[2] > 17)) {
        $d = DateTime::createFromFormat($format, $date);
    } else {
        $d = new DateTime(date($format, strtotime($date)));
    }
    return $d && $d->format($format) == $date;
}
up
1
ystein M
5 years ago
I think there is an error in the function from bmauser below. $regexp is overwritten. Here's another version which also accepts missing zeros and two digits year notation.

This function checks date if matches given format and validity of the date.

<?php
/**
* Checks date if matches given format and validity of the date.
* Examples:
* <code>
* is_date('22.22.2222', 'mm.dd.yyyy'); // returns false
* is_date('11/30/2008', 'mm/dd/yyyy'); // returns true
* is_date('30-01-2008', 'dd-mm-yyyy'); // returns true
* is_date('2008 01 30', 'yyyy mm dd'); // returns true
* </code>
* @param string $value the variable being evaluated.
* @param string $format Format of the date. Any combination of <i>mm<i>, <i>dd<i>, <i>yyyy<i>
* with single character separator between.
*/
function is_valid_date($value, $format = 'dd.mm.yyyy'){
    if(
strlen($value) >= 6 && strlen($format) == 10){
       
       
// find separator. Remove all other characters from $format
       
$separator_only = str_replace(array('m','d','y'),'', $format);
       
$separator = $separator_only[0]; // separator is first character
       
       
if($separator && strlen($separator_only) == 2){
           
// make regex
           
$regexp = str_replace('mm', '(0?[1-9]|1[0-2])', $format);
           
$regexp = str_replace('dd', '(0?[1-9]|[1-2][0-9]|3[0-1])', $regexp);
           
$regexp = str_replace('yyyy', '(19|20)?[0-9][0-9]', $regexp);
           
$regexp = str_replace($separator, "\\" . $separator, $regexp);
            if(
$regexp != $value && preg_match('/'.$regexp.'\z/', $value)){

               
// check date
               
$arr=explode($separator,$value);
               
$day=$arr[0];
               
$month=$arr[1];
               
$year=$arr[2];
                if(@
checkdate($month, $day, $year))
                    return
true;
            }
        }
    }
    return
false;
}
?>

[NOTE BY danbrown AT php DOT net: Original function was written by (bmauser AT gmail) on 16-DEC-2008.]
up
-1
sebagr@gmail
5 years ago
Here's a nice snippet to check if user input is valid:

<?php

$date_format
= 'Y-m-d';
$input = '2009-03-03';

$input = trim($input);
$time = strtotime($input);

$is_valid = date($date_format, $time) == $input;

print
"Valid? ".($is_valid ? 'yes' : 'no');

?>
up
-4
bharath.kishore.a AT gmail. DOT com
2 years ago
Here is another crooked way to check if given data is valid DATETIME or not.

function checkDateTime($data) {
    if (date('Y-m-d H:i:s', strtotime($data)) == $data) {
        return true;
    } else {
        return false;
    }
}
up
-1
SDSurfer
14 days ago
Super graceful solution by glavic and the mod by Bas - the only thing I would add is if you have user input, you have the potential for really munged up values for date which can throw exceptions. Add a try/catch:

    if (((int) $version[0] >= 5 && (int) $version[1] >= 2 && (int) $version[2] > 17)) {
        try {  $d = DateTime::createFromFormat($format, $date); }
        catch (Exception $e) {
            if ($debug) { echo "Invalid date: " . $e->getMessage() . "<br>\n"; }
            return false;
        }
    } else {
        try { $d = new DateTime(date($format, strtotime($date))); }
        catch (Exception $e) {
            if ($debug) { echo "Invalid date: " . $e->getMessage() . "<br>\n"; }
            return false;
        }
    }
up
-3
venadder at yahoo dot ca
5 years ago
Here is a simple IsDate function, using purely PHP functions( A Check for $Stamp can be added to see if it's a legal Unix timestamp ):

<?php
function IsDate( $Str )
{
 
$Stamp = strtotime( $Str );
 
$Month = date( 'm', $Stamp );
 
$Day   = date( 'd', $Stamp );
 
$Year  = date( 'Y', $Stamp );

  return
checkdate( $Month, $Day, $Year );
}
?>
up
-5
rfeugenio at gmail dot com
5 years ago
<?php

// This is a simple function that will get the last day of the month.

function GetLastDayofMonth($year, $month) {
    for (
$day=31; $day>=28; $day--) {
        if (
checkdate($month, $day, $year)) {
            return
$day;
        }
    }   
}

?>
up
-11
jdiosdado
10 months ago
There is an issue with glavic at gmail dot com answer:

var_dump(validateDate('9/21/1943', ''m/d/Y''));

The result will be false. 09/21/1943  =! 9/21/1943
up
-9
mohammed dot aas2012 at gmail dot com
1 year ago
format should be in array like: array("m","d","y")

<?php
function isValidDate($strDate,$format,$ex) {
     
$valid = false;
      if(
is_array($format) && count($format) == 3 && count(explode($ex,$strDate))==3)
      {
        
$date = array_combine($format,explode($ex,$strDate));
         if(
intval($date['m']) && intval($date['d']) && intval($date['y'])){
           
$m = $date['m']; $d = $date['d']; $y = $date['y'];
           
$valid = checkdate($m,$d,$y);
         }
      }
      return
$valid;
   }
?>
up
-7
a34 at yahoo dot com
7 years ago
checkData function posted below does not consider a date entered such as 03/27c/2000.   The c will cause it to crash.  Here is the fix.

<?php
function checkData($mydate) {
      
    list(
$yy,$mm,$dd)=explode("-",$mydate);
    if (
is_numeric($yy) && is_numeric($mm) && is_numeric($dd))
    {
        return
checkdate($mm,$dd,$yy);
    }
    return
false;           
}
?>
up
-8
James Luckhurst
5 years ago
<?php
/*
## converts a given date format to another date format returns date if the checked date given is valid; otherwise returns NULL
## $s_date the date in e.g. dd/mm/yyyy
## $s_from, $s_to date formats from to i.e. convertdate('13/04/2009','eng','iso','-'); output: 2009-04-13
## date formats available
## 'eng' = dd/mm/yyyy
## 'usa' = mm/dd/yyyy
## 'iso' = yyyy/mm/dd
## $s_return_delimiter returned delimiter e.g. '-' would return dd-mm-yyyy
*/
function convertdate($s_date,$s_from,$s_to,$s_return_delimiter) {

   
$s_return_date = '';
   
$s_from = strtolower($s_from);
   
$s_to = strtolower($s_to);
   
$s_date = str_replace(array('\'', '-', '.', ',', ' '), '/', $s_date);
   
$a_date = explode('/', $s_date);
   
    switch(
$s_from) {
        case
'eng': # dd/mm/yyyy
           
$day = $a_date[0];
           
$month = $a_date[1];
           
$year = $a_date[2];
        break;
        case
'usa'# mm/dd/yyyy
           
$month = $a_date[0];
           
$day = $a_date[1];
           
$year = $a_date[2];
        break;
        case
'iso': # yyyy/mm/dd
           
$year = $a_date[0];
           
$month = $a_date[1];
           
$day = $a_date[2];
        break;
        default:
# error message
           
user_error('function convertdate(string $s_date, string $s_from, string $s_to, string $s_return_delimiter) $s_from not a valid type of \'eng\', \'usa\' or \'iso\'');
            return
NULL;
    }

   
# substitution fixes of valid alternative human input e.g. 1/12/08
   
if (strlen($day)==1) { $day='0'.$day; } # day -trailing zero missing
   
if (strlen($month)==1) { $month='0'.$month; } # month -trailing zero missing
   
if (strlen($year)==3) { $year=substr(date('Y'),0,strlen(date('Y'))-3).$year; } # year -millennium missing
   
if (strlen($year)==2) { $year=substr(date('Y'),0,strlen(date('Y'))-2).$year; } # year -century missing
   
if (strlen($year)==1) { $year=substr(date('Y'),0,strlen(date('Y'))-1).$year; } # year -decade missing

   
switch($s_to) {
        case
'eng': # dd/mm/yyyy
           
$s_return_date = $day.$s_return_delimiter.$month.$s_return_delimiter.$year;
        break;
        case
'usa'# mm/dd/yyyy
           
$s_return_date = $month.$s_return_delimiter.$day.$s_return_delimiter.$year;
        break;
        case
"iso": # yyyy/mm/dd
           
$s_return_date = $year.$s_return_delimiter.$month.$s_return_delimiter.$day;
        break;
        default:
# error message
           
user_error('function convertdate(string $s_date, string $s_from, string $s_to, string $s_return_delimiter) $s_to not a valid type of \'eng\', \'usa\' or \'iso\'');
            return
NULL;
    }

   
# if it's an invalid calendar date e.g. 40/02/2009 or rt/we/garbage
   
if (!is_numeric($month) || !is_numeric($day) || !is_numeric($year)) {
        return
NULL;
    } elseif (!
checkdate($month, $day, $year)) {
        return
NULL;
    }

    return
$s_return_date;
}

echo
convertdate('13/04/2009','eng','iso','-');
?>
up
-8
admin at limitsizbilgi dot com
1 year ago
function DDC($dates){ // Date Day Control
    $dy = substr($dates,0,4);
    $dm = substr($dates,5,2);
    $dd = substr($dates,8,2);
    for($i=0; $i<3; $i++){
        if(!checkdate($dm,$dd,$dy)){
            $dd--;
        }else{$i=3;}
    }
    return $dy.'.'.$dm.'.'.$dd;
}
echo DDC('2013.02.31');
//2013.02.28
To Top