1.20.x date.class.inc | protected BackdropDateTime::parse($date, $tz, $format) |
Converts a date string into a date object.
Parameters
string $date: The date string to parse.
object $tz: A timezone object.
string $format: The date format string.
Return value
object: Returns the date object.
File
- includes/
date.class.inc, line 429
Class
- BackdropDateTime
- Extends PHP DateTime class for use with Backdrop.
Code
protected function parse($date, $tz, $format) {
$array = date_format_patterns();
foreach ($array as $key => $value) {
// The letter with no preceding '\'.
$patterns[] = "`(^|[^\\\\\\\\])" . $key . "`";
// A single character.
$repl1[] = '${1}(.)';
// The.
$repl2[] = '${1}(' . $value . ')';
}
$patterns[] = "`\\\\\\\\([" . implode(array_keys($array)) . "])`";
$repl1[] = '${1}';
$repl2[] = '${1}';
$format_regexp = preg_quote($format);
// Extract letters.
$regex1 = preg_replace($patterns, $repl1, $format_regexp, 1);
$regex1 = str_replace('A', '(.)', $regex1);
$regex1 = str_replace('a', '(.)', $regex1);
preg_match('`^' . $regex1 . '$`', stripslashes($format), $letters);
array_shift($letters);
// Extract values.
$regex2 = preg_replace($patterns, $repl2, $format_regexp, 1);
$regex2 = str_replace('A', '(AM|PM)', $regex2);
$regex2 = str_replace('a', '(am|pm)', $regex2);
preg_match('`^' . $regex2 . '$`u', $date, $values);
array_shift($values);
// If we did not find all the values for the patterns in the format, abort.
if (count($letters) != count($values)) {
$this->errors['invalid'] = t('The value @date does not match the expected format.', array('@date' => $date));
return FALSE;
}
$this->granularity = array();
$final_date = array(
'hour' => 0,
'minute' => 0,
'second' => 0,
'month' => 1,
'day' => 1,
'year' => 0,
);
foreach ($letters as $i => $letter) {
$value = $values[$i];
switch ($letter) {
case 'd':
case 'j':
$final_date['day'] = intval($value);
$this->addGranularity('day');
break;
case 'n':
case 'm':
$final_date['month'] = intval($value);
$this->addGranularity('month');
break;
case 'F':
$array_month_long = array_flip(date_month_names());
$final_date['month'] = array_key_exists($value, $array_month_long) ? $array_month_long[$value] : -1;
$this->addGranularity('month');
break;
case 'M':
$array_month = array_flip(date_month_names_abbr());
$final_date['month'] = array_key_exists($value, $array_month) ? $array_month[$value] : -1;
$this->addGranularity('month');
break;
case 'Y':
$final_date['year'] = $value;
$this->addGranularity('year');
if (strlen($value) < 4) {
$this->errors['year'] = t('The year is invalid. Please check that entry includes four digits.');
}
break;
case 'y':
$year = $value;
// If no century, we add the current one ("06" => "2006").
$final_date['year'] = str_pad($year, 4, substr(date("Y"), 0, 2), STR_PAD_LEFT);
$this->addGranularity('year');
break;
case 'a':
case 'A':
$ampm = strtolower($value);
break;
case 'g':
case 'h':
case 'G':
case 'H':
$final_date['hour'] = intval($value);
$this->addGranularity('hour');
break;
case 'i':
$final_date['minute'] = intval($value);
$this->addGranularity('minute');
break;
case 's':
$final_date['second'] = intval($value);
$this->addGranularity('second');
break;
case 'U':
parent::__construct($value, $tz ? $tz : new DateTimeZone("UTC"));
$this->addGranularity('year');
$this->addGranularity('month');
$this->addGranularity('day');
$this->addGranularity('hour');
$this->addGranularity('minute');
$this->addGranularity('second');
return $this;
}
}
if (isset($ampm) && $ampm == 'pm' && $final_date['hour'] < 12) {
$final_date['hour'] += 12;
}
elseif (isset($ampm) && $ampm == 'am' && $final_date['hour'] == 12) {
$final_date['hour'] -= 12;
}
// Blank becomes current time, given TZ.
parent::__construct('', $tz ? $tz : new DateTimeZone("UTC"));
if ($tz) {
$this->addGranularity('timezone');
}
// SetDate expects an integer value for the year, results can be unexpected
// if we feed it something like '0100' or '0000'.
$final_date['year'] = intval($final_date['year']);
$this->errors += $this->arrayErrors($final_date);
$granularity = backdrop_map_assoc($this->granularity);
// If the input value is '0000-00-00', PHP's date class will later
// incorrectly convert it to something like '-0001-11-30' if we do setDate()
// here. If we don't do setDate() here, it will default to the current date
// and we will lose any way to tell that there was no date in the orignal
// input values. So set a flag we can use later to tell that this date
// object was created using only time values, and that the date values are
// artifical.
if (empty($final_date['year']) && empty($final_date['month']) && empty($final_date['day'])) {
$this->timeOnly = TRUE;
}
elseif (empty($this->errors)) {
// setDate() expects a valid year, month, and day.
// Set some defaults for dates that don't use this to
// keep PHP from interpreting it as the last day of
// the previous month or last month of the previous year.
if (empty($granularity['month'])) {
$final_date['month'] = 1;
}
if (empty($granularity['day'])) {
$final_date['day'] = 1;
}
$this->setDate($final_date['year'], $final_date['month'], $final_date['day']);
}
if (!isset($final_date['hour']) && !isset($final_date['minute']) && !isset($final_date['second'])) {
$this->dateOnly = TRUE;
}
elseif (empty($this->errors)) {
$this->setTime($final_date['hour'], $final_date['minute'], $final_date['second']);
}
return $this;
}