8000 minor #17435 [Clock] Documentation for new Clock component (dbrumann) · jderusse/symfony-docs@c9b27cb · GitHub
[go: up one dir, main page]

Skip to content

Commit c9b27cb

Browse files
committed
minor symfony#17435 [Clock] Documentation for new Clock component (dbrumann)
This PR was merged into the 6.2 branch. Discussion ---------- [Clock] Documentation for new Clock component Closes symfony#17074 Commits ------- 24e3994 [Clock] Documentation for new Clock component
2 parents 83cd877 + 24e3994 commit c9b27cb

File tree

1 file changed

+105
-0
lines changed

1 file changed

+105
-0
lines changed

components/clock.rst

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
.. index::
2+
single: Clock
3+
single: Components; Clock
4+
5+
The Clock Component
6+
===================
7+
8+
.. versionadded:: 6.2
9+
10+
The Clock component was introduced in Symfony 6.2
11+
12+
The Clock component decouples applications from the system clock. This allows
13+
you to fix time to improve testability of time-sensitive logic.
14+
15+
The component provides a ``ClockInterface`` with the following implementations
16+
for different use cases:
17+
18+
:class:`Symfony\\Component\\Clock\\NativeClock`
19+
Provides a way to interact with the system clock, this is the same as doing
20+
``new \DateTimeImmutable()``.
21+
:class:`Symfony\\Component\\Clock\\MockClock`
22+
Commonly used in tests as a replacement for the ``NativeClock`` to be able
23+
to freeze and change the current time using either ``sleep()`` or ``modify()``.
24+
:class:`Symfony\\Component\\Clock\\MonotonicClock``
25+
Relies on ``hrtime()`` and provides a high resolution, monotonic clock,
26+
when you need a precise stopwatch.
27+
28+
Installation
29+
------------
30+
31+
.. code-block:: terminal
32+
33+
$ composer require symfony/clock
34+
35+
.. include:: /components/require_autoload.rst.inc
36+
37+
NativeClock
38+
-----------
39+
40+
A clock service replaces creating a new ``DateTime`` or
41+
``DateTimeImmutable`` object for the current time. Instead, you inject the
42+
``ClockInterface`` and call ``now()``. By default, your application will likely
43+
use a ``NativeClock``, which always returns the current system time. In tests it is replaced with a ``MockClock``.
44+
45+
The following example introduces a service utilizing the Clock component to
46+
determine the current time::
47+
48+
use Symfony\Component\Clock\ClockInterface;
49+
50+
class ExpirationChecker
51+
{
52+
public function __construct(
53+
private readonly ClockInterface $clock
54+
) {}
55+
56+
public function isExpired(DateTimeInterface $validUntil): bool
57+
{
58+
return $this->clock->now() > $validUntil;
59+
}
60+
}
61+
62+
MockClock
63+
---------
64+
65+
The ``MockClock`` is instantiated with a time and does not move forward on its own. The time is
66+
fixed until ``sleep()`` or ``modify()`` are called. This gives you full control over what your code
67+
assumes is the current time.
68+
69+
When writing a test for this service, you can check both cases where something
70+
is expired or not, by modifying the clock's time::
71+
72+
use PHPUnit\Framework\TestCase;
73+
use Symfony\Component\Clock\MockClock;
74+
75+
class ExpirationCheckerTest extends TestCase
76+
{
77+
public function testIsExpired(): void
78+
{
79+
$clock = new MockClock('2022-11-16 15:20:00');
80+
$expirationChecker = new ExpirationChecker($clock);
81+
$validUntil = new DateTimeImmutable('2022-11-16 15:25:00');
82+
83+
// $validUntil is in the future, so it is not expired
84+
static::assertFalse($expirationChecker->isExpired($validUntil));
85+
86+
// Clock sleeps for 10 minutes, so now is '2022-11-16 15:30:00'
87+
$clock->sleep(600); // Instantly changes time as if we waited for 10 minutes (600secs)
88+
89+
// modify the clock, accepts all formats supported by DateTimeImmutable::modify()
90+
static::assertTrue($expirationChecker->isExpired($validUntil));
91+
92+
$clock->modify('2022-11-16 15:00:00');
93+
94+
// $validUntil is in the future again, so it is no longer expired
95+
static::assertFalse($expirationChecker->isExpired($validUntil));
96+
}
97+
}
98+
99+
Monotonic Clock
100+
---------------
101+
102+
The ``MonotonicClock`` allows you to implement a precise stopwatch, depending on the system up to
103+
nanosecond precision. It can be used to measure the elapsed time between 2 calls without being
104+
affected by inconsistencies sometimes introduced by the system clock, e.g. by updating it. Instead,
105+
it consistently increases time, making it especially useful for measuring performance.

0 commit comments

Comments
 (0)
0