[0-9]{4} # century year (?:0[1-9]|1[0-2]) # month (?:0[1-9]|[12][0-9]|3[0-1]) # day (?:[01][0-9]|2[0-3]) # hour ) (?: (?P[0-5][0-9]) # minute (?P[0-5][0-9]|60)? # second or leap-second )? (?:[.,](?P[0-9]+))? # fraction (?P # g-time-zone Z | [-+] (?:[01][0-9]|2[0-3]) # hour (?:[0-5][0-9])? # minute ) \z/x EOD; $matches = array(); if (preg_match($generalizedTimePattern, $value, $matches)) { $dateTimeRaw = $matches['YmdH']; $dateTimeFormat = 'YmdH'; if ($matches['i'] !== '') { $dateTimeRaw .= $matches['i']; $dateTimeFormat .= 'i'; if ($matches['s'] !== '') { $dateTimeRaw .= $matches['s']; $dateTimeFormat .= 's'; $fractionOfSeconds = 1; } else { $fractionOfSeconds = 60; } } else { $fractionOfSeconds = 3600; } $dateTimeFormat .= 'O'; if ($matches['tz'] === 'Z') { $dateTimeRaw .= '+0000'; } else { $dateTimeRaw .= $matches['tz']; if (strlen($matches['tz']) === 3) { $dateTimeRaw .= '00'; } } $dateTime = DateTime::createFromFormat($dateTimeFormat, $dateTimeRaw); if ($dateTime !== false) { if (isset($matches['frac'])) { $dateTime->add(new DateInterval( 'PT' . round((float) ('0.' . $matches['frac']) * $fractionOfSeconds) . 'S' )); } return $dateTime; } } throw new InvalidArgumentException(sprintf( 'Failed to parse %s based on the ASN.1 standard (GeneralizedTime)', var_export($value, true) )); } }