agent/php/ElasticApm/Impl/Util/TimeUtil.php (118 lines of code) (raw):
<?php
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
declare(strict_types=1);
namespace Elastic\Apm\Impl\Util;
/**
* Code in this file is part of implementation internals and thus it is not covered by the backward compatibility.
*
* @internal
*/
final class TimeUtil
{
use StaticClassTrait;
public const NUMBER_OF_NANOSECONDS_IN_MICROSECOND = 1000;
public const NUMBER_OF_MICROSECONDS_IN_MILLISECOND = 1000;
public const NUMBER_OF_MILLISECONDS_IN_SECOND = 1000;
public const NUMBER_OF_MICROSECONDS_IN_SECOND = self::NUMBER_OF_MILLISECONDS_IN_SECOND * self::NUMBER_OF_MICROSECONDS_IN_MILLISECOND;
public const NUMBER_OF_SECONDS_IN_MINUTE = 60;
public const NUMBER_OF_MINUTES_IN_HOUR = 60;
public const NUMBER_OF_HOURS_IN_DAY = 24;
/**
* @param float $beginTime Begin time in microseconds
* @param float $endTime End time in microseconds
*
* @return float Duration in microseconds
*
* @see ClockInterface::getMonotonicClockCurrentTime() For the description
*/
public static function calcDurationInMicrosecondsClampNegativeToZero(float $beginTime, float $endTime): float
{
return ($endTime >= $beginTime) ? ($endTime - $beginTime) : 0;
}
/**
* @param float $beginTime Begin time in microseconds
* @param float $endTime End time in microseconds
*
* @return float Duration in milliseconds
*
* @see ClockInterface::getMonotonicClockCurrentTime() For the description
*/
public static function calcDurationInMillisecondsClampNegativeToZero(float $beginTime, float $endTime): float
{
return self::microsecondsToMilliseconds(
self::calcDurationInMicrosecondsClampNegativeToZero($beginTime, $endTime)
);
}
public static function microsecondsToMilliseconds(float $microseconds): float
{
return $microseconds / self::NUMBER_OF_MICROSECONDS_IN_MILLISECOND;
}
public static function millisecondsToMicroseconds(float $milliseconds): float
{
return $milliseconds * self::NUMBER_OF_MICROSECONDS_IN_MILLISECOND;
}
public static function nanosecondsToMicroseconds(float $nanoseconds): float
{
return $nanoseconds / self::NUMBER_OF_NANOSECONDS_IN_MICROSECOND;
}
public static function secondsToMicroseconds(float $seconds): float
{
return $seconds * self::NUMBER_OF_MICROSECONDS_IN_SECOND;
}
public static function microsecondsToSeconds(float $microseconds): float
{
return $microseconds / self::NUMBER_OF_MICROSECONDS_IN_SECOND;
}
private static function calcWholeTimesAndRemainderForFloat(
float $largeVal,
int $smallVal,
float &$wholeTimes,
float &$remainder
): void {
$wholeTimes = floor($largeVal / $smallVal);
$remainder = $largeVal - ($smallVal * $wholeTimes);
}
public static function formatDurationInMicroseconds(float $durationInMicroseconds): string
{
if ($durationInMicroseconds === 0.0) {
return '0us';
}
$isNegative = ($durationInMicroseconds < 0);
$microsecondsTotalFloat = abs($durationInMicroseconds);
$microsecondsTotalWhole = floor($microsecondsTotalFloat);
$microsecondsFraction = $microsecondsTotalFloat - $microsecondsTotalWhole;
$millisecondsTotalWhole = 0.0;
$microsecondsRemainder = 0.0;
self::calcWholeTimesAndRemainderForFloat(
$microsecondsTotalWhole,
TimeUtil::NUMBER_OF_MICROSECONDS_IN_MILLISECOND,
/* ref */ $millisecondsTotalWhole,
/* ref */ $microsecondsRemainder
);
$secondsTotalWhole = 0.0;
$millisecondsRemainder = 0.0;
self::calcWholeTimesAndRemainderForFloat(
$millisecondsTotalWhole,
TimeUtil::NUMBER_OF_MILLISECONDS_IN_SECOND,
/* ref */ $secondsTotalWhole,
/* ref */ $millisecondsRemainder
);
$minutesTotalWhole = 0.0;
$secondsRemainder = 0.0;
self::calcWholeTimesAndRemainderForFloat(
$secondsTotalWhole,
TimeUtil::NUMBER_OF_SECONDS_IN_MINUTE,
/* ref */ $minutesTotalWhole,
/* ref */ $secondsRemainder
);
$hoursTotalWhole = 0.0;
$minutesRemainder = 0.0;
self::calcWholeTimesAndRemainderForFloat(
$minutesTotalWhole,
TimeUtil::NUMBER_OF_MINUTES_IN_HOUR,
/* ref */ $hoursTotalWhole,
/* ref */ $minutesRemainder
);
$hoursRemainder = 0.0;
$daysTotalWhole = 0.0;
self::calcWholeTimesAndRemainderForFloat(
$hoursTotalWhole,
TimeUtil::NUMBER_OF_HOURS_IN_DAY,
/* ref */ $daysTotalWhole,
/* ref */ $hoursRemainder
);
$appendRemainder = function (string $appendTo, float $remainder, string $units): string {
if ($remainder === 0.0) {
return $appendTo;
}
$remainderAsString = ($remainder === floor($remainder)) ? strval(intval($remainder)) : strval($remainder);
return $appendTo . (TextUtil::isEmptyString($appendTo) ? '' : ' ') . $remainderAsString . $units;
};
$result = '';
$result = $appendRemainder($result, $daysTotalWhole, 'd');
$result = $appendRemainder($result, $hoursRemainder, 'h');
$result = $appendRemainder($result, $minutesRemainder, 'm');
$result = $appendRemainder($result, $secondsRemainder, 's');
$result = $appendRemainder($result, $millisecondsRemainder, 'ms');
$result = $appendRemainder($result, $microsecondsRemainder + $microsecondsFraction, 'us');
return ($isNegative ? '-' : '') . $result;
}
}