Completed
Push — master ( 9da68c...45336e )
by Alexander
02:18
created

Producer::circle()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 12
ccs 9
cts 9
cp 1
rs 9.8666
c 0
b 0
f 0
cc 4
nc 8
nop 2
crap 4
1
<?php
2
namespace GetSky\AIRAC;
3
4
/**
5
 * Class Producer
6
 * @deprecated Use AiracProducer. This class will be removed in version 1.2.0
7
 * @package GetSky\AIRAC
8
 */
9
class Producer
10
{
11
    /**
12
     * @var \DateTime
13
     */
14
    private $bearing;
15
16
    /**
17
     * @param \DateTime|null $bearing
18
     */
19 45
    public function __construct(\DateTime $bearing = null)
20
    {
21 45
         $this->bearing = $bearing ? $bearing : new \DateTime('2016-01-07');
22 45
    }
23
24
    /**
25
     * @return \DateTime
26
     */
27 2
    public function getBearingDate(): \DateTime
28
    {
29 2
        return $this->bearing;
30
    }
31
32
    /**
33
     * Get next AIRAC date.
34
     *
35
     * @param \DateTime $date
36
     * @return Airac
37
     */
38 6
    public function next(\DateTime $date): Airac
39
    {
40 6
        return $this->circle($date, 1);
41
    }
42
43
    /**
44
     * Get next AIRAC date.
45
     *
46
     * @param string $number
47
     * @return Airac
48
     * @throws AiracNumberValidationException
49
     */
50 13
    public function nextByNumber(string $number): Airac
51
    {
52 13
        return $this->circleByNumber($number, 1);
53
    }
54
55
    /**
56
     * Get current AIRAC date.
57
     *
58
     * @param \DateTime $date
59
     * @return Airac
60
     */
61 6
    public function now(\DateTime $date): Airac
62
    {
63 6
        return $this->circle($date, 0);
64
    }
65
66
    /**
67
     * Get current AIRAC date.
68
     *
69
     * @param string $number
70
     * @return Airac
71
     * @throws AiracNumberValidationException
72
     */
73 6
    public function nowByNumber(string $number): Airac
74
    {
75 6
        return $this->circleByNumber($number, 0);
76
    }
77
78
    /**
79
     * Get last AIRAC date.
80
     *
81
     * @param \DateTime $date
82
     * @return Airac
83
     */
84 6
    public function last(\DateTime $date): Airac
85
    {
86 6
        return $this->circle($date, -1);
87
    }
88
89
    /**
90
     * Get last AIRAC date.
91
     *
92
     * @param string $number
93
     * @return Airac
94
     * @throws AiracNumberValidationException
95
     */
96 6
    public function lastByNumber(string $number): Airac
97
    {
98 6
        return $this->circleByNumber($number, -1);
99
    }
100
101
    /**
102
     * Generator AIRAC dates.
103
     *
104
     * @param \DateTime $date
105
     * @param $step
106
     * @return Airac
107
     */
108 36
    private function circle(\DateTime $date, int $step): Airac
109
    {
110 36
        $positive = ($date >= $this->bearing) ? 1 : -1;
111 36
        $days = $date->diff($this->bearing)->days;
112 36
        $countCircle = $positive * floor($days / 28) + $step - (($positive < 0 && $days % 28 != 0) ? 1 : 0);
113 36
        $dateStart = clone $this->bearing;
114 36
        $dateStart->modify(($countCircle * 28) . ' day');
115 36
        $dateEnd = clone $dateStart;
116 36
        $dateEnd->modify('28 day');
117
118 36
        return new Airac($dateStart, $dateEnd, $this->calcNumber($dateStart));
119
    }
120
121
    /**
122
     * Generator AIRAC dates.
123
     *
124
     * @param string $number
125
     * @param int $step
126
     * @return Airac
127
     * @throws AiracNumberValidationException
128
     */
129 25
    private function circleByNumber(string $number, int $step): Airac
130
    {
131 25
        if (preg_match("/[0-9]{4}/", $number) === 0) {
132 7
            throw new AiracNumberValidationException("Number '$number' isn't correct AIRAC.");
133
        }
134
135 18
        $date = \DateTime::createFromFormat('!y', substr($number, 0, 2));
136 18
        if ($date === false) {
137
            throw new AiracNumberValidationException("It is impossible to extract the year of the cycle '$number'.");
138
        }
139
140 18
        return $this->circle($date, $step + substr($number, 2, 2));
141
    }
142
143
    /**
144
     *Calculated number of AIRAC.
145
     *
146
     * @param \DateTime $date
147
     * @return string
148
     */
149 36
    private function calcNumber(\DateTime $date): string
150
    {
151 36
        $year = \DateTime::createFromFormat('!Y', $date->format('Y'));
152 36
        $number = 1 + floor($year->diff($date)->days / 28);
153
        
154 36
        return $year->format('y') . sprintf("%02d", $number);
155
    }
156
}
157