You are here

function _scheduler_strptime in Scheduler 7

Same name and namespace in other branches
  1. 5 scheduler.module \_scheduler_strptime()
  2. 6 scheduler.module \_scheduler_strptime()

Parse a time/date as UTC time.

The php function strptime() has a limited life, due to it returning varying results on different operating systems. It is not supported on Windows platforms at all. The replacement function date_parse_from_format() is not as flexible as strptime(), for example it forces two-digit minutes and seconds. _scheduler_strptime() gives us more control over the entities that are parsed and how the matching is achieved.

Parameters

string $date: The string to parse.

string $format: The date format used in $date. For details on the date format options, see the PHP date() function.

Return value

int The parsed time converted to a UTC timestamp using mktime().

1 call to _scheduler_strptime()
_scheduler_strtotime in ./scheduler.module
Converts a time string from the user's timezone into a Unix timestamp.

File

./scheduler.module, line 340
Scheduler publishes and unpublishes nodes on dates specified by the user.

Code

function _scheduler_strptime($date, $format) {

  // Build a regex pattern for each element allowed in the date and time format.
  $date_entities_and_replacements = array(
    // Date elements, one for each character in SCHEDULER_DATE_LETTERS.
    // Inline comments on each row are useful here, so 'ignore' for standards.
    // @codingStandardsIgnoreStart
    'd' => '(\\d{2})',
    // Day of the month with leading zero.
    'j' => '(\\d{1,2})',
    // Day of the month without leading zero.
    'm' => '(\\d{2})',
    // Month number with leading zero.
    'n' => '(\\d{1,2})',
    // Month number without leading zero.
    'M' => '(\\w{3})',
    // Three-letter month abbreviation.
    'F' => '(\\w{3,9})',
    // Full month name, from 3 to 9 letters.
    'y' => '(\\d{2})',
    // Two-digit year.
    'Y' => '(\\d{4})',
    // Four-digit year.
    // Time elements, one for each character in SCHEDULER_TIME_LETTERS.
    'h' => '(\\d{2})',
    // Hours in 12-hour format with leading zero.
    'H' => '(\\d{2})',
    // Hours in 24-hour format with leading zero.
    'g' => '(\\d{1,2})',
    // Hours in 12-hour format without leading zero.
    'G' => '(\\d{1,2})',
    // Hours in 24-hour format without leading zero.
    'i' => '(\\d{2})',
    // Minutes with leading zero.
    's' => '(\\d{2})',
    // Seconds with leading zero.
    'a' => '([ap]m)',
    // Lower case meridian.
    'A' => '([AP]M)',
  );
  $date_entities = array_keys($date_entities_and_replacements);
  $date_regex_replacements = array_values($date_entities_and_replacements);
  $custom_pattern = str_replace($date_entities, $date_regex_replacements, $format);
  if (!preg_match("#{$custom_pattern}#", $date, $value_matches)) {
    return FALSE;
  }
  if (!preg_match_all('/(\\w)/', $format, $entity_matches)) {
    return FALSE;
  }
  $results = array(
    'day' => 0,
    'month' => 0,
    'year' => 0,
    'hour' => 0,
    'minute' => 0,
    'second' => 0,
    'meridiem' => NULL,
  );
  $index = 1;
  foreach ($entity_matches[1] as $entity) {
    $value = intval($value_matches[$index]);
    switch ($entity) {
      case 'd':
      case 'j':
        $results['day'] = $value;
        break;
      case 'm':
      case 'n':
        $results['month'] = $value;
        break;
      case 'M':
      case 'F':

        // Derive a time value from the matched month name text.
        $temp_time = strtotime($value_matches[$index]);
        if (empty($temp_time)) {

          // If the text is not a valid month name or abbreviation then fail.
          return FALSE;
        }

        // Derive the month number from the month name.
        $results['month'] = date('n', $temp_time);
        break;
      case 'y':
      case 'Y':
        $results['year'] = $value;
        break;
      case 'H':
      case 'h':
      case 'g':
      case 'G':
        $results['hour'] = $value;
        break;
      case 'i':
        $results['minute'] = $value;
        break;
      case 's':
        $results['second'] = $value;
        break;
      case 'a':
      case 'A':
        $results['meridiem'] = $value_matches[$index];
        break;
    }
    $index++;
  }
  if (strncasecmp($results['meridiem'], "pm", 2) == 0 && $results['hour'] < 12) {
    $results['hour'] += 12;
  }
  if (strncasecmp($results['meridiem'], "am", 2) == 0 && $results['hour'] == 12) {
    $results['hour'] -= 12;
  }
  $time = mktime($results['hour'], $results['minute'], $results['second'], $results['month'], $results['day'], $results['year']);
  return $time;
}