* @package oat\tao\helpers */ class DateIntervalMS extends \DateInterval { public $u = 0; protected static $interval_spec_regex = "/ ^ ## start of the string P ## first character must be a P (?:(?P\d+)Y)? ## year (?:(?P\d+)M)? ## month (?:(?P\d+)D)? ## day (?:T ## T delineates between day and time information (?:(?P\d+)H)? ## hour (?:(?P\d+)M)? ## minute (?:(?P\d+(?:\.\d+)?)S)? ## seconds as float. )? ## closes 'T' subexpression $ ## end of the string /x"; /** * Formatting for current date interval * @param $format * @return string */ public function format($format) { $format = str_replace('%U', sprintf("%06d", $this->u), $format); $format = str_replace('%u', sprintf("%d", intval($this->u)), $format); return parent::format($format); } /** * Convert microseconds to seconds in float type * @param $microseconds * @return float */ public static function microsecondsToSeconds($microseconds) { $microseconds = intval($microseconds); $seconds = round($microseconds / 1000000, 6); return $seconds; } /** * Convert seconds with microseconds as fraction to amount of microseconds * @param $seconds * @return int */ public static function secondsToMicroseconds($seconds) { $seconds = round($seconds, 6); $microseconds = intval($seconds * 1000000); return $microseconds; } /** * Build valid DateInterval format * @param array $parts * @return string */ private static function getLegacySpec(array $parts) { $spec = "P"; $spec .= $parts['y'] !== "" ? "{$parts['y']}Y" : ""; $spec .= $parts['m'] !== "" ? "{$parts['m']}M" : ""; $spec .= $parts['d'] !== "" ? "{$parts['d']}D" : ""; if ($parts['h'] . $parts['i'] . $parts['s'] !== "") { $spec .= "T"; $spec .= $parts['h'] !== "" ? "{$parts['h']}H" : ""; $spec .= $parts['i'] !== "" ? "{$parts['i']}M" : ""; $spec .= $parts['s'] !== "" ? "{$parts['s']}S" : ""; } if ($spec === "P") { $spec = ""; } return $spec; } /** * Custom construct with support microseconds * @param string $interval_spec */ public function __construct($interval_spec) { if (!preg_match(static::$interval_spec_regex, $interval_spec, $parts)) { throw new \UnexpectedValueException(sprintf("%s::%s: Unknown or bad format (%s)", get_called_class(), '__construct', $interval_spec)); } if (isset($parts['s'])) { $preciseSeconds = floatval($parts['s']); $microseconds = static::secondsToMicroseconds(fmod($preciseSeconds, 1.0)); $seconds = floor($preciseSeconds); $this->u = $microseconds; $parts['s'] = $seconds; } $legacy_spec = static::getLegacySpec($parts); parent::__construct($legacy_spec); } }