|
24 | 24 | @dataclasses.dataclass(frozen=True) |
25 | 25 | class Instant: |
26 | 26 | """ |
27 | | - Measures a span of time between different points in the code. |
| 27 | + Represents an instant in time, used to both get the timestamp value and to measure |
| 28 | + the duration of a time span. |
28 | 29 |
|
29 | 30 | Inspired by Rust's `std::time::Instant`. |
30 | 31 | """ |
31 | 32 |
|
32 | 33 | # Creation time of this instant, using time.time(), to measure actual time. |
33 | 34 | # Use a `lambda` to initialize the default to correctly get the mocked time via `MockTiming`. |
34 | | - _start_time: float = dataclasses.field(default_factory=lambda: time(), init=False) |
| 35 | + time: float = dataclasses.field(default_factory=lambda: time(), init=False) |
35 | 36 |
|
36 | | - # Initial "tick" of the performance counter to measure precise elapsed time. |
| 37 | + # Performance counter tick of the instant, used to measure precise elapsed time. |
37 | 38 | # Use a `lambda` to initialize the default to correctly get the mocked time via `MockTiming`. |
38 | | - _start_perf: float = dataclasses.field( |
| 39 | + perf_count: float = dataclasses.field( |
39 | 40 | default_factory=lambda: perf_counter(), init=False |
40 | 41 | ) |
41 | 42 |
|
42 | 43 | def duration(self) -> Duration: |
43 | 44 | """Measure the duration since `Instant` was created.""" |
44 | | - return Duration( |
45 | | - start=self._start_time, |
46 | | - elapsed_s=perf_counter() - self._start_perf, |
47 | | - stop=time(), |
48 | | - ) |
| 45 | + return Duration(start=self, stop=Instant()) |
| 46 | + |
| 47 | + def as_utc(self) -> datetime: |
| 48 | + """Instant as UTC datetime.""" |
| 49 | + return datetime.fromtimestamp(self.time, timezone.utc) |
49 | 50 |
|
50 | 51 |
|
51 | 52 | @dataclasses.dataclass(frozen=True) |
52 | 53 | class Duration: |
53 | 54 | """A span of time as measured by `Instant.duration()`.""" |
54 | 55 |
|
55 | | - # Start time of the duration, as seconds since epoch. |
56 | | - start: float |
57 | | - # Stop time of the duration, as seconds since epoch. |
58 | | - stop: float |
59 | | - # Elapsed time of the duration, in seconds, measured using a performance counter for precise timing. |
60 | | - elapsed_s: float |
61 | | - |
62 | | - def start_utc(self) -> datetime: |
63 | | - """Start time of the duration, as a datetime in UTC.""" |
64 | | - return datetime.fromtimestamp(self.start, timezone.utc) |
| 56 | + start: Instant |
| 57 | + stop: Instant |
65 | 58 |
|
66 | | - def stop_utc(self) -> datetime: # pragma: no cover |
67 | | - """Stop time of the duration, as a datetime in UTC.""" |
68 | | - return datetime.fromtimestamp(self.stop, timezone.utc) |
| 59 | + @property |
| 60 | + def elapsed_s(self) -> float: |
| 61 | + """Elapsed time of the duration, in seconds, measured using a performance counter for precise timing.""" |
| 62 | + return self.stop.perf_count - self.start.perf_count |
69 | 63 |
|
70 | 64 |
|
71 | 65 | @dataclasses.dataclass |
|
0 commit comments