Passed
Push — master ( 5b4064...cd467c )
by Valentin
17:10 queued 13:04
created

ThresholdChecker::date()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 5
c 1
b 0
f 0
nc 3
nop 1
dl 0
loc 11
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Spiral\Validation\Checker\DatetimeChecker;
6
7
class ThresholdChecker
8
{
9
    /**
10
     * Check if date comes before the given one. Do not compare if the given date is missing or invalid.
11
     *
12
     * @param \DateTimeInterface|null $value
13
     * @param \DateTimeInterface|null $threshold
14
     * @param bool                    $orEquals
15
     * @param bool                    $useMicroSeconds
16
     * @return bool
17
     */
18
    public function before(
19
        ?\DateTimeInterface $value,
20
        ?\DateTimeInterface $threshold,
21
        bool $orEquals = false,
22
        bool $useMicroSeconds = false
23
    ): bool {
24
        $compare = $this->compare($this->date($value), $this->date($threshold), $useMicroSeconds);
25
        if (is_bool($compare)) {
26
            return $compare;
27
        }
28
29
        return $orEquals ? $compare <= 0 : $compare < 0;
30
    }
31
32
    /**
33
     * Check if date comes after the given one. Do not compare if the given date is missing or invalid.
34
     *
35
     * @param \DateTimeInterface|null $value
36
     * @param \DateTimeInterface|null $threshold
37
     * @param bool                    $orEquals
38
     * @param bool                    $useMicroSeconds
39
     * @return bool
40
     */
41
    public function after(
42
        ?\DateTimeInterface $value,
43
        ?\DateTimeInterface $threshold,
44
        bool $orEquals = false,
45
        bool $useMicroSeconds = false
46
    ): bool {
47
        $compare = $this->compare($this->date($value), $this->date($threshold), $useMicroSeconds);
48
        if (is_bool($compare)) {
49
            return $compare;
50
        }
51
52
        return $orEquals ? $compare >= 0 : $compare > 0;
53
    }
54
55
    /**
56
     * @param mixed $value
57
     * @return \DateTimeImmutable|null
58
     */
59
    private function date($value): ?\DateTimeImmutable
60
    {
61
        if ($value instanceof \DateTimeImmutable) {
62
            return $value;
63
        }
64
65
        if ($value instanceof \DateTime) {
66
            return \DateTimeImmutable::createFromMutable($value);
67
        }
68
69
        return null;
70
    }
71
72
    /**
73
     * @param \DateTimeImmutable|null $date
74
     * @param \DateTimeImmutable|null $threshold
75
     * @param bool                    $useMicroseconds
76
     * @return bool|int
77
     */
78
    private function compare(?\DateTimeImmutable $date, ?\DateTimeImmutable $threshold, bool $useMicroseconds)
79
    {
80
        if ($date === null) {
81
            return false;
82
        }
83
84
        if ($threshold === null) {
85
            return true;
86
        }
87
88
        if (!$useMicroseconds) {
89
            $date = $this->dropMicroSeconds($date);
90
            $threshold = $this->dropMicroSeconds($threshold);
91
        }
92
93
        return $date <=> $threshold;
94
    }
95
96
    /**
97
     * @param \DateTimeImmutable $date
98
     * @return \DateTimeImmutable
99
     */
100
    private function dropMicroSeconds(\DateTimeImmutable $date): \DateTimeImmutable
101
    {
102
        return $date->setTime(
103
            (int)$date->format('H'),
104
            (int)$date->format('i'),
105
            (int)$date->format('s')
106
        );
107
    }
108
}
109