Passed
Push — master ( 8d88d2...f31554 )
by Andy
01:13
created

DateTime::isSameOrAfter()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Palmtree\Chrono;
4
5
use Palmtree\Chrono\Option\Comparision;
6
use Palmtree\Chrono\Option\DatePeriod;
7
use Palmtree\Chrono\Option\TimePeriod;
8
9
class DateTime
10
{
11
    /** @var \DateTime */
12
    protected $dateTime;
13
14 23
    public function __construct(string $time = 'now', $timezone = null)
15
    {
16 23
        if (is_string($timezone)) {
17 1
            $timezone = new \DateTimeZone($timezone);
18
        }
19
20 23
        $this->dateTime = new \DateTime($time, $timezone);
21 23
    }
22
23 1
    protected function getFormatFromTimePrecision(?string $precision): string
24
    {
25
        try {
26 1
            $format = TimePeriod::getDateFormat($precision ?? TimePeriod::SECOND);
27 1
        } catch (\InvalidArgumentException $e) {
28 1
            $format = DatePeriod::getDateFormat($precision ?? DatePeriod::DAY);
29
        }
30
31 1
        return $format;
32
    }
33
34 6
    protected function getDateInterval(int $value, string $period): \DateInterval
35
    {
36
        try {
37 6
            $intervalCode = TimePeriod::getIntervalCode($period);
38 4
            $prefix = 'PT';
39 4
        } catch (\InvalidArgumentException $e) {
40 4
            $intervalCode = DatePeriod::getIntervalCode($period);
41 4
            $prefix = 'P';
42
        }
43
44 6
        return new \DateInterval("$prefix$value$intervalCode");
45
    }
46
47 21
    public function format(string $format): string
48
    {
49 21
        return $this->dateTime->format($format);
50
    }
51
52 8
    public function isSame(DateTime $date, ?string $precision = null): bool
53
    {
54 8
        return $this->compareTo($date, Comparision::EQUAL_TO, $precision);
55
    }
56
57 3
    public function isBefore(DateTime $date, ?string $precision = null): bool
58
    {
59 3
        return $this->compareTo($date, Comparision::LESS_THAN, $precision);
60
    }
61
62 1
    public function isSameOrBefore(DateTime $date, ?string $precision = null): bool
63
    {
64 1
        return $this->compareTo($date, Comparision::LESS_THAN_OR_EQUAL_TO, $precision);
65
    }
66
67 3
    public function isAfter(DateTime $date, ?string $precision = null): bool
68
    {
69 3
        return $this->compareTo($date, Comparision::GREATER_THAN, $precision);
70
    }
71
72 1
    public function isSameOrAfter(DateTime $date, ?string $precision = null): bool
73
    {
74 1
        return $this->compareTo($date, Comparision::GREATER_THAN_OR_EQUAL_TO, $precision);
75
    }
76
77 3
    public function add(int $value, string $period): self
78
    {
79 3
        $this->dateTime->add($this->getDateInterval($value, $period));
80
81 3
        return $this;
82
    }
83
84 3
    public function subtract(int $value, string $period): self
85
    {
86 3
        $this->dateTime->sub($this->getDateInterval($value, $period));
87
88 3
        return $this;
89
    }
90
91 1
    public function toDateTime(): \DateTime
92
    {
93 1
        return clone $this->dateTime;
94
    }
95
96 2
    public static function min(...$dates): ?DateTime
97
    {
98
        return \array_reduce($dates, function (?DateTime $carry, DateTime $dateTime) {
99 2
            if (!$carry || $dateTime->isBefore($carry)) {
100 2
                $carry = $dateTime;
101
            }
102
103 2
            return $carry;
104 2
        });
105
    }
106
107 2
    public static function max(...$dates): ?DateTime
108
    {
109
        return \array_reduce($dates, function (?DateTime $carry, DateTime $dateTime) {
110 2
            if (!$carry || $dateTime->isAfter($carry)) {
111 2
                $carry = $dateTime;
112
            }
113
114 2
            return $carry;
115 2
        });
116
    }
117
118 16
    private function compareTo(DateTime $date, string $operator, ?string $precision = null): bool
119
    {
120 16
        $format = $this->getFormatFromTimePrecision($precision);
121
122 15
        $operandLeft  = (int)$this->format($format);
123 15
        $operandRight = (int)$date->format($format);
124
125
        switch ($operator) {
126 15
            case Comparision::EQUAL_TO:
127
            default:
128 7
                $result = $operandLeft === $operandRight;
129 7
                break;
130 8
            case Comparision::LESS_THAN:
131 3
                $result = $operandLeft < $operandRight;
132 3
                break;
133 5
            case Comparision::GREATER_THAN:
134 3
                $result = $operandLeft > $operandRight;
135 3
                break;
136 2
            case Comparision::LESS_THAN_OR_EQUAL_TO:
137 1
                $result = $operandLeft <= $operandRight;
138 1
                break;
139 1
            case Comparision::GREATER_THAN_OR_EQUAL_TO:
140 1
                $result = $operandLeft >= $operandRight;
141 1
                break;
142
        }
143
144 15
        return $result;
145
    }
146
}
147