Created
November 11, 2014 18:24
-
-
Save imhoffd/a1754193bde215b6509f to your computer and use it in GitHub Desktop.
strptime2 - parses dates given a format
This file contains hidden or 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
<?php | |
require 'strptime2.php'; | |
echo '<pre>'; | |
echo strptime2('12/29/1989', 'm/d/Y') . "\n"; | |
echo strptime2('7/15/1989 10:13am', 'n/d/Y h:ia') . "\n"; | |
echo strptime2('07/15/1989 10:13AM', 'm/d/Y h:iA') . "\n"; | |
echo strptime2('Sep 12, 2013 22:12', 'M j, Y H:i') . "\n"; | |
echo strptime2('Thursday, July 26, 2012 - 2:48:12PM', 'l, F j, Y - g:i:sA') . "\n"; | |
echo strptime2('February 29, 2008', 'F d, Y') . "\n"; // leap year | |
echo '</pre>'; |
This file contains hidden or 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
<?php | |
/** | |
* A strptime() alternative. | |
* | |
* Large amounts of this code were inspired by the Drupal module Scheduler's | |
* _scheduler_strptime() function as well as the comment left on php.net: | |
* http://www.php.net/manual/en/function.strptime.php#82004 | |
* | |
* @param string $time | |
* The string to be turned into a Unix Timestamp. | |
* @param string $format | |
* The string representing a format understood by date(). | |
* | |
* @return int | |
* The integer that represents a Unix Timestamp or FALSE if failure. | |
* | |
* @see | |
* date() | |
*/ | |
function strptime2($time, $format) { | |
// This associative array maps characters that the date() function understands | |
// with their regex validator. | |
$characters = array( | |
'/' => '\/', | |
'd' => '(\d{2})', | |
'D' => '(\w{3})', | |
'j' => '(\d{1,2})', | |
'l' => '(\w{6,9})', | |
'F' => '(\w{3,9})', | |
'm' => '(\d{2})', | |
'M' => '(\w{3})', | |
'n' => '(\d{1,2})', | |
'o' => '(\d{4})', | |
'Y' => '(\d{4})', | |
'y' => '(\d{2})', | |
'a' => '([ap]m)', | |
'A' => '([AP]M)', | |
'g' => '(\d{1,2})', | |
'G' => '(\d{1,2})', | |
'h' => '(\d{2})', | |
'H' => '(\d{2})', | |
'i' => '(\d{2})', | |
's' => '(\d{2})', | |
); | |
$format_matches = array(); | |
// Get an array of characters that match a character the date() function can | |
// understand. | |
if (!preg_match_all('/(\w)/', $format, $format_matches)) { | |
return FALSE; | |
} | |
// Build a regular expression based upon the format. | |
$format = str_replace(array_keys($characters), array_values($characters), preg_quote($format)); | |
// Get an array of values that match the regular expression we built. | |
if (!preg_match('/' . $format . '/', $time, $time_matches)) { | |
return FALSE; | |
} | |
$i = 0; | |
// We use $format_matches as a parallel array of $time_matches to get the | |
// actual value of each part of the $time string. | |
foreach ($format_matches[0] as $character) { | |
++$i; | |
switch ($character) { | |
case 'd': | |
case 'j': | |
$day = (int) $time_matches[$i]; | |
break; | |
case 'm': | |
case 'n': | |
$month = (int) $time_matches[$i]; | |
break; | |
case 'F': | |
case 'M': | |
$month_numbers = array( | |
'Jan' => 1, | |
'Feb' => 2, | |
'Mar' => 3, | |
'Apr' => 4, | |
'May' => 5, | |
'Jun' => 6, | |
'Jul' => 7, | |
'Aug' => 8, | |
'Sep' => 9, | |
'Oct' => 10, | |
'Nov' => 11, | |
'Dec' => 12, | |
); | |
$month = $month_numbers[substr($time_matches[$i], 0, 3)]; | |
break; | |
case 'o': | |
case 'Y': | |
case 'y': | |
$year = (int) $time_matches[$i]; | |
break; | |
case 'a': | |
case 'A': | |
$meridiem = strtolower($time_matches[$i]); | |
break; | |
case 'g': | |
case 'G': | |
case 'h': | |
case 'H': | |
$hour = (int) $time_matches[$i]; | |
break; | |
case 'i': | |
$minute = (int) $time_matches[$i]; | |
break; | |
case 's': | |
$second = (int) $time_matches[$i]; | |
break; | |
} | |
} | |
// These are required to create a Unix Timestamp with mktime(). | |
if (!isset($month) || !isset($day) || !isset($year)) { | |
return FALSE; | |
} | |
// A time cannot be in 24 hour format with an AM or PM as well. | |
if (isset($meridiem) && isset($hour) && $hour > 12) { | |
return FALSE; | |
} | |
// If it's PM and not 12:##PM, add 12 hours for 24 hour format. | |
if (isset($meridiem) && $meridiem == 'pm' && $hour < 12) { | |
$hour += 12; | |
} | |
// If it's 12:##am, it's 00:## in 24 hour format. | |
if (isset($meridiem) && $meridiem == 'am' && $hour == 12) { | |
$hour = 0; | |
} | |
// If mktime() failed, at this point.. this function will fail. | |
if (FALSE === $time = mktime(isset($hour) ? $hour : 0, isset($minute) ? $minute : 0, isset($second) ? $second : 0, $month, $day, $year)) { | |
return FALSE; | |
} | |
return $time; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment