This simple tip allow you to detect if the date is typed correctly and the date format is as expected.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* | |
* Check if the given date is valid | |
* @param string $date | |
* | |
* @param string $separator | |
* | |
* @param string $format defines the order which year month and day are in the $date string | |
* this string supports "d" for days "m" for month and "y" for year | |
* | |
* @param int|bool $lower2DigitsDate (optional default 1950) if the given date is | |
* defined as 2 digits value it will be adjusted | |
* according to this value if the parameter is false | |
* the correction will not be performed | |
* | |
* @example $date = '2012-08-30'; $validDate = isValidDate($date, '-', 'ymd'); | |
* @example $date = '30/08/2012'; $validDate = isValidDate($date, '/', 'dmy'); | |
* @example $date = '08/30/2012'; $validDate = isValidDate($date, '/', 'mdy'); | |
* @example $date = '08/30/12'; $validDate = isValidDate($date, '/', 'mdy'); | |
* | |
* @return boolean | |
*/ | |
function isValidDate($date, $separator = '/', $format = 'dmy', $lower2DigitsDate = 1950){ | |
/* | |
* Detect the Datetime structure | |
*/ | |
$yearIndex = strpos($format, 'y'); | |
$monthIndex = strpos($format, 'm'); | |
$dayIndex = strpos($format, 'd'); | |
/* | |
* split the string date into an array of three elements according to given separator | |
*/ | |
$dateElements = preg_split('#'. preg_quote($separator, '#') . '#', $date); | |
/* | |
* Check for EXACT 3 parts in the date | |
*/ | |
if(count($dateElements)!=3) return false; | |
$day = intval($dateElements[$dayIndex]); | |
$month = intval($dateElements[$monthIndex]); | |
$year = intval($dateElements[$yearIndex]); | |
/* | |
* Convert 2 digits year in 4 digits year | |
*/ | |
if($year<100 && $lower2DigitsDate !==false){ | |
$marker = ($lower2DigitsDate%100); | |
if($year<$marker) $year += 100; | |
$year = $lower2DigitsDate-$marker + $year; | |
$dateElements[$yearIndex] = $year; | |
} | |
$monthDays = array( 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30,31); | |
/** | |
* Exception on introduction of Gregorian Calendar | |
* @see http://diegolamonica.info/howto-detect-if-typed-date-is-valid/#comment-5426 | |
*/ | |
if($year==1582 && $month==10 && $day>4 && $day<15) return false; | |
/** | |
* Feb has 29 days in the leap years | |
* @see http://en.wikipedia.org/wiki/Leap_year#Algorithm | |
*/ | |
$leapYear = ($year % 4 == 0 && ($year % 100 != 0 || $year % 400 == 0) ); | |
if($leapYear) $monthDays[2] = 29; | |
// Output the adjusted date (with 4 digits year) | |
$date = implode($separator, $dateElements); | |
/* | |
* Check if the day of the month is into the range | |
*/ | |
return ($monthDays[$month] >= $day && $day>0); | |
} |
Commenti
6 risposte a “Howto detect if typed date is valid”
Riddle: catch the bug.
where is the function lack?
Hi Giacomo,
trying the following code:
Hi Giacomo,
trying the following code:
the output is as expected. So… where is the bug? :)
Think: which was the day after 4th October 1582 ?
It was the October, 5th 1582, not? :)
no, it wasn’t!
the day after 4th october, was 15th october, according to Gregorian calendar.
….but ….
…but…. there are many consideration we could do. (i.e. Swedish Reign used Giulian (Assange) calendar till 1699)
touche! :)
Thanks Giacomo! As you can notice, I’ve changed the script.