#native_company# #native_desc#
#native_cta#

MyDate

By William Nettmann
on February 7, 2004

Version: 1.0

Type: Function

Category: Calendars/Dates

License: GNU General Public License

Description: Function which validates and converts into a Unix timestamp almost any form of text date without resorting to drop down boxes, etc on web pages. Accepts days and years in numbers, and months as numbers, abbreviations or full names in English, eg 21/January/04 or 21 jan 2004 – can use -, / or space as delimiter. When in doubt, will assume dd/mm/yy was input – that’s the norm where I live. Please mail me if you have any comments or suggestions – this is a work in progress!

<?php

/*A bit of code to test the function:
echo "This function should be able to make sense of almost any date thrown at it. It will return a Unix timestamp for a date string.";
$testdate = "";
if(isset($_GET["date"])) $testdate = $_GET["date"];
echo "<form action='mydate.php'>Date: <input type='text' name='date' value='$testdate'><input type='submit'></form>";
if(isset($_GET["date"])) $date = mydate($testdate);
else die();
echo "<br>";
if(!$date) echo "<br>Invalid date!";
else echo "<br>Date is ".strftime("%d/%m/%Y",$date)." or in PHP Unix form, $date";*/

function mydate($date){
	// Date may be in Unix format already:
	if($date*1 >= 79200) return $date;
	// Date cannot be shorter than 5 characters:
	if(strlen($date) < 5) return false;

	// Standardise date seperators to "/":
	$date = str_replace(", ","/",$date);
	$date = str_replace(" ,","/",$date);
	$date = str_replace(" , ","/",$date);
	$date = str_replace(" ","/",$date);
	$date = str_replace(",","/",$date);
	$date = str_replace("-","/",$date);

	// Split date into three seperate parts:
	$parts = explode("/",$date);
	if(count($parts) != 3) return false; // Date must have three parts.
	$part1 = $parts[0];
	$part2 = $parts[1];
	$part3 = $parts[2];
	
	// Check if there is a month in text somewhere:
	$longmonths = array("january","february","march","april","may","june",
							"july","august","september","october","november","december");
	$shortmonths = array("jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec");
	while(list($key,$month) = each($longmonths)){
		if(strtolower($part1) == $month or strtolower($part1) == $shortmonths[$key]){
			$part1 = $key+1;
			$month = "part1";
			break;
		}
		if(strtolower($part2) == $month or strtolower($part2) == $shortmonths[$key]){
			$part2 = $key+1;
			$month = "part2";
			break;
		}
		if(strtolower($part3) == $month or strtolower($part3) == $shortmonths[$key]){
			$part3 = $key+1;
			$month = "part3";
			break;
		}  
	}
	if(!isset($month)){ // Check if two parts are > 12 - the other is probably month, or it is an invalid date.
		if($part1 > 12 and $part2 > 12) $month = "part3";
		if($part1 > 12 and $part3 > 12) $month = "part2";
		if($part2 > 12 and $part3 > 12) $month = "part1";
	}
	if(isset($month)){
		if($$month > 12) return false;
		$m = $$month;
		unset($$month);
		$datearray = false;
		if(isset($part1) and isset($part2)) $datearray = choosedayandyear($m,$part1,$part2);
		if(!$datearray) if(isset($part1) and isset($part2)) $datearray = choosedayandyear($m,$part2,$part1);
		if(!$datearray) if(isset($part1) and isset($part3)) $datearray = choosedayandyear($m,$part1,$part3);
		if(!$datearray) if(isset($part1) and isset($part3)) $datearray = choosedayandyear($m,$part3,$part1);
		if(!$datearray) if(isset($part2) and isset($part3)) $datearray = choosedayandyear($m,$part2,$part3);
		if(!$datearray) if(isset($part2) and isset($part3)) $datearray = choosedayandyear($m,$part3,$part2);
		if(!$datearray) return false;
	}
	
	else{// Deduce format according to the magnitude of each part:
		$datearray = examinedate($part1,$part2,$part3);
		if(!$datearray) $datearray = examinedate($part3,$part1,$part2);
		if(!$datearray) $datearray = examinedate($part2,$part3,$part1);
		
	}
	
	if($datearray){
		$d = $datearray[0];
		$m = $datearray[1];
		$y = $datearray[2];
	}
	else{ // Assume d/m/y if all else fails!
		$d = $part1;
		$m = $part2;
		$y = $part3;
		if(($m == 1 or $m == 3 or $m == 5 or $m == 7 or $m == 8 or $m == 10 or $m == 12) and $d > 31) return false;
		if(($m == 4 or $m == 6 or $m == 9 or $m == 11) and $d > 30) return false;
		if($m == 2 and 0 != fmod($y,4) and $d > 28) return false;
		if($m == 2 and $d > 28) return false;
	}
	if($y < 70) $y += 2000;
	elseif($y < 1900) $y += 1900;
	if($y <= 1969 or $y >= 2038) return false; // Windows can't cope with dates beyond this range - sorry!
	return strtotime($m."/".$d."/".$y);
}

function examinedate($p1,$p2,$p3){
	if($p1 > 31){ // must be year
		if($p2 > 31 or $p3 > 31) return false; // must be invalid
		$y = $p1;
		if($p2 > 12){ // must be day
			$d = $p2;
			if($p3 > 12) return false; // must be invalid
			$m = $p3;
		}
		elseif($p3 > 12){ // 2 must be month!
			$m = $p2;
			$d = $p3;
		}
		else{ // both p2 and p3 are less than 12, so could be either day or month - assume y/m/d
			$d = $p2;
			$m = $p3;
		}
	}
	else return false; // Inconclusive
	return array($d,$m,$y);
	
}

function choosedayandyear($m,$p1,$p2){
	if($m == 1 or $m == 3 or $m == 5 or $m == 7 or $m == 8 or $m == 10 or $m == 12){
		if($p1 > 31 and $p2 <= 31){
			$d = $p2;
			$y = $p1;
			return array($d,$m,$y);
		}
	}
	if($m == 4 or $m == 6 or $m == 9 or $m == 11){
		if($p1 > 30 and $p2 <= 30){
			$d = $p2;
			$y = $p1;
			return array($d,$m,$y);
		}
	}
	if($m == 2){
		if($p1 == 29 and 0 == fmod($p2,4)){
			$d = $p1;
			$y = $p2;
			return array($d,$m,$y);
		}
		elseif($p1 > 28){
			if($p2 > 28) return false;
			$y = $p1;
			$d = $p2;
			return array($d,$m,$y);
		}
	}
	return false;
}
?>