RewindableDateTimeClock::create()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php declare(strict_types=1);
2
3
namespace Stratadox\Clock;
4
5
use DateInterval;
6
use DateTimeInterface;
7
8
/**
9
 * RewindableDateTimeClock. This clock can be rewinded- or fast-forwarded as
10
 * needed. This implementation is immutable; alterations to the time offset
11
 * apply only to the returned copy of the clock, the original instance is not
12
 * affected.
13
 *
14
 * @author Stratadox
15
 */
16
final class RewindableDateTimeClock implements RewindableClock
17
{
18
    private $clock;
19
    private $rewinds = [];
20
    private $fastForwards = [];
21
22
    private function __construct(Clock $clock)
23
    {
24
        $this->clock = $clock;
25
    }
26
27
    public static function create(): RewindableClock
28
    {
29
        return new self(DateTimeClock::create());
30
    }
31
32
    public static function using(Clock $originalClock): RewindableClock
33
    {
34
        return new self($originalClock);
35
    }
36
37
    public function rewind(DateInterval $interval): RewindableClock
38
    {
39
        $new = clone $this;
40
        $new->rewinds[] = $interval;
41
        return $new;
42
    }
43
44
    public function fastForward(DateInterval $interval): RewindableClock
45
    {
46
        $new = clone $this;
47
        $new->fastForwards[] = $interval;
48
        return $new;
49
    }
50
51
    public function now(): DateTimeInterface
52
    {
53
        $datetime = $this->clock->now();
54
        foreach ($this->rewinds as $rewind) {
55
            $datetime = $datetime->sub($rewind);
56
        }
57
        foreach ($this->fastForwards as $fastForward) {
58
            $datetime = $datetime->add($fastForward);
59
        }
60
        return $datetime;
61
    }
62
}
63