File: Clock.php

package info (click to toggle)
mediawiki 1%3A1.43.3%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 417,464 kB
  • sloc: php: 1,062,949; javascript: 664,290; sql: 9,714; python: 5,458; xml: 3,489; sh: 1,131; makefile: 64
file content (53 lines) | stat: -rw-r--r-- 1,482 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<?php
namespace Wikimedia\Telemetry;

use Wikimedia\Assert\Assert;

/**
 * A click providing the current time in nanoseconds, backed by {@link hrtime}.
 *
 * @since 1.43
 * @internal
 */
class Clock {
	/**
	 * Timestamp to return in place of the current time, or `null` to use the current time.
	 * @var int|null
	 */
	private static ?int $mockTime = null;

	/**
	 * The reference UNIX timestamp in nanoseconds which hrtime() offsets should be added to
	 * to derive an absolute timestamp.
	 * @var int|null
	 */
	private ?int $referenceTime = null;

	public function __construct() {
		Assert::precondition(
			PHP_INT_SIZE >= 8,
			'The Clock class requires 64-bit integers to support nanosecond timing'
		);
	}

	/**
	 * Get the current time, represented as the number of nanoseconds since the UNIX epoch.
	 * @return int
	 */
	public function getCurrentNanoTime(): int {
		$this->referenceTime ??= (int)( 1e9 * microtime( true ) ) - hrtime( true );
		return self::$mockTime ?? ( $this->referenceTime + hrtime( true ) );
	}

	/**
	 * Set a mock time to override the timestamp returned by {@link Clock::getCurrentNanoTime()}.
	 * Useful for testing.
	 *
	 * @param int|null $epochNanos The override timestamp, or `null` to return to using the current time.
	 * @return void
	 */
	public static function setMockTime( ?int $epochNanos ): void {
		Assert::precondition( defined( 'MW_PHPUNIT_TEST' ), 'This method should only be used in tests' );
		self::$mockTime = $epochNanos;
	}
}