Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
Clock
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 3
12
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 getCurrentNanoTime
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 setMockTime
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2namespace Wikimedia\Telemetry;
3
4use Wikimedia\Assert\Assert;
5
6/**
7 * A click providing the current time in nanoseconds, backed by {@link hrtime}.
8 *
9 * @since 1.43
10 * @internal
11 */
12class Clock {
13    /**
14     * Timestamp to return in place of the current time, or `null` to use the current time.
15     * @var int|null
16     */
17    private static ?int $mockTime = null;
18
19    /**
20     * The reference UNIX timestamp in nanoseconds which hrtime() offsets should be added to
21     * to derive an absolute timestamp.
22     * @var int|null
23     */
24    private ?int $referenceTime = null;
25
26    public function __construct() {
27        Assert::precondition(
28            PHP_INT_SIZE >= 8,
29            'The Clock class requires 64-bit integers to support nanosecond timing'
30        );
31    }
32
33    /**
34     * Get the current time, represented as the number of nanoseconds since the UNIX epoch.
35     */
36    public function getCurrentNanoTime(): int {
37        $this->referenceTime ??= (int)( 1e9 * microtime( true ) ) - hrtime( true );
38        return self::$mockTime ?? ( $this->referenceTime + hrtime( true ) );
39    }
40
41    /**
42     * Set a mock time to override the timestamp returned by {@link Clock::getCurrentNanoTime()}.
43     * Useful for testing.
44     *
45     * @param int|null $epochNanos The override timestamp, or `null` to return to using the current time.
46     * @return void
47     */
48    public static function setMockTime( ?int $epochNanos ): void {
49        Assert::precondition( defined( 'MW_PHPUNIT_TEST' ), 'This method should only be used in tests' );
50        self::$mockTime = $epochNanos;
51    }
52}