You are here

function date_convert_from_custom in Date 5.2

Same name and namespace in other branches
  1. 6.2 date_api_elements.inc \date_convert_from_custom()
  2. 6 date_api_elements.inc \date_convert_from_custom()

Convert a date input in a custom format to a standard date type

Handles conversion of translated month names (i.e. turns t('Mar') or t('March') into 3). Also properly handles dates input in European style short formats, like DD/MM/YYYY. Works by parsing the format string to create a regex that can be used on the input value.

The original code to do this was created by Yves Chedemois (yched).

Parameters

string $date: a date value

string $format: a date format string that describes the format of the input value

Return value

mixed input value converted to a DATE_DATETIME value

5 calls to date_convert_from_custom()
date_popup_input_value in date_popup/date_popup.module
Helper function for extracting a date value out of user input.
date_popup_process in date_popup/date_popup.module
Javascript popup element processing. Add popup attributes to $element.
date_text_input_value in ./date_api_elements.inc
Helper function for extracting a date value out of user input.
date_text_process in ./date_api_elements.inc
Text date input form.
_date_views_filter_handler in date/date_views.inc

File

./date_api_elements.inc, line 572
Date API elements themes and validation. This file is only included during the edit process to reduce memory usage.

Code

function date_convert_from_custom($date, $format) {
  $array = date_format_patterns();
  foreach ($array as $key => $value) {
    $patterns[] = "`(^|[^\\\\\\\\])" . $key . "`";

    // the letter with no preceding '\'
    $repl1[] = '${1}(.)';

    // a single character
    $repl2[] = '${1}(' . $value . ')';

    // the
  }
  $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 . '$`', $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)) {
    return NULL;
  }
  $final_date = array(
    'hour' => 0,
    'minute' => 0,
    'second' => 0,
    'month' => 0,
    'day' => 0,
    'year' => 0,
  );
  foreach ($letters as $i => $letter) {
    $value = $values[$i];
    switch ($letter) {
      case 'd':
      case 'j':
        $final_date['day'] = intval($value);
        break;
      case 'n':
      case 'm':
        $final_date['month'] = intval($value);
        break;
      case 'F':
        $array_month_long = array_flip(date_month_names());
        $final_date['month'] = $array_month_long[$value];
        break;
      case 'M':
        $array_month = array_flip(date_month_names_abbr());
        $final_date['month'] = $array_month[$value];
        break;
      case 'Y':
      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);
        break;
      case 'a':
      case 'A':
        $ampm = strtolower($value);
        break;
      case 'g':
      case 'h':
      case 'G':
      case 'H':
        $final_date['hour'] = intval($value);
        break;
      case 'i':
        $final_date['minute'] = intval($value);
        break;
      case 's':
        $final_date['second'] = intval($value);
        break;
      case 'U':
        return date_convert($value, DATE_UNIX, DATE_DATETIME);
        break;
    }
  }
  if ($ampm == 'pm' && $final_date['hour'] < 12) {
    $final_date['hour'] += 12;
  }
  elseif ($ampm == 'am' && $final_date['hour'] == 12) {
    $final_date['hour'] -= 12;
  }

  // Don't test for valid date, we might use this to extract
  // incomplete date part info from user input.
  return date_convert($final_date, DATE_ARRAY, DATE_DATETIME);
}