Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
64.29% covered (warning)
64.29%
18 / 28
35.71% covered (danger)
35.71%
5 / 14
CRAP
0.00% covered (danger)
0.00%
0 / 1
Stopwatch
64.29% covered (warning)
64.29%
18 / 28
35.71% covered (danger)
35.71%
5 / 14
30.17
0.00% covered (danger)
0.00%
0 / 1
 startNew
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 isRunning
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 start
83.33% covered (warning)
83.33%
5 / 6
0.00% covered (danger)
0.00%
0 / 1
2.02
 stop
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 restart
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getElapsed
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 toString
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getUnixTime
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getUnixMicroTime
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getCurrentTime32
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getCurrentTime64
75.00% covered (warning)
75.00%
3 / 4
0.00% covered (danger)
0.00%
0 / 1
2.06
 getCurrentTime
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 nanoToMilliseconds
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 __toString
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3declare(strict_types=1);
4
5namespace PeServer\Core;
6
7use Stringable;
8use PeServer\Core\Throws\InvalidOperationException;
9use PeServer\Core\Throws\NotSupportedException;
10use PeServer\Core\Throws\StopwatchWException;
11
12/**
13 * `HRTime\StopWatch` 的な。
14 *
15 * あと簡単な時間系処理のラッパー。
16 */
17class Stopwatch implements Stringable
18{
19    #region variable
20
21    /** 計測中か。 */
22    private bool $isRunning = false;
23    /** 計測開始時間。 */
24    private int $startTime = 0;
25    /** 計測終了時間。 */
26    private int $stopTime = 0;
27
28    #endregion
29
30    #region function
31
32    /**
33     * インスタンス生成しつつ計測開始。
34     *
35     * @return self
36     */
37    public static function startNew(): self
38    {
39        $result = new self();
40        $result->start();
41        return $result;
42    }
43
44    /**
45     * 計測中か。
46     *
47     * @return bool
48     */
49    public function isRunning(): bool
50    {
51        return $this->isRunning;
52    }
53
54    /**
55     * 計測開始。
56     *
57     * @throws InvalidOperationException 現在計測中。
58     */
59    public function start(): void
60    {
61        if ($this->isRunning) {
62            throw new InvalidOperationException();
63        }
64
65        $this->isRunning = true;
66        $time = self::getCurrentTime();
67        $this->startTime = $time;
68        $this->stopTime = $time;
69    }
70
71    /**
72     * 計測終了。
73     */
74    public function stop(): void
75    {
76        $this->stopTime = self::getCurrentTime();
77        $this->isRunning = false;
78    }
79
80    public function restart(): void
81    {
82        $this->stop();
83        $this->start();
84    }
85
86    /**
87     * 現在の経過時間(ナノ秒)を取得。
88     *
89     * * 計測中であれば計測開始からの経過時間
90     * * 計測終了であれば計測開始からの計測終了までの経過時間。
91     *
92     * @return int
93     */
94    public function getElapsed(): int
95    {
96        if ($this->isRunning) {
97            return self::getCurrentTime() - $this->startTime;
98        }
99
100        return $this->stopTime - $this->startTime;
101    }
102
103    /**
104     * ミリ秒として文字列化。
105     *
106     * @return string
107     */
108    public function toString(): string
109    {
110        return self::nanoToMilliseconds($this->getElapsed()) . ' msec';
111    }
112
113    /**
114     * 現在のUNIX時間(秒)を取得。
115     *
116     * `time` ラッパー。
117     *
118     * @return int
119     * @see https://www.php.net/manual/function.time.php
120     */
121    public static function getUnixTime(): int
122    {
123        return time();
124    }
125
126    /**
127     * 現在のUNIX時間(マイクロ秒)を取得。
128     *
129     * `microtime` ラッパー。
130     *
131     * @return float
132     * @see https://www.php.net/manual/function.microtime.php
133     */
134    public static function getUnixMicroTime(): float
135    {
136        return microtime(true);
137    }
138
139    //@phpstan-ignore-next-line 32bit(笑)
140    private static function getCurrentTime32(): float|false
141    {
142        throw new NotSupportedException();
143    }
144    /**
145     * 64bit環境用 `hrtime`
146     *
147     * @return int
148     */
149    private static function getCurrentTime64(): int
150    {
151        $result = hrtime(true);
152        if ($result === false) { //@phpstan-ignore-line 失敗したら false 返ってくるっぽいんだけどなぁ
153            throw new StopwatchWException();
154        }
155
156        return $result;
157    }
158    /**
159     * 現在のナノ秒を取得。
160     *
161     * @return int
162     */
163    public static function getCurrentTime(): int
164    {
165        return self::getCurrentTime64();
166    }
167
168    public static function nanoToMilliseconds(int $nanoSec): float
169    {
170        return $nanoSec / 1e+6;
171    }
172
173    #endregion
174
175    #region Stringable
176
177    public function __toString(): string
178    {
179        return $this->toString();
180    }
181
182    #endregion
183}