Time::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 3
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace Popy\Calendar\ValueObject;
4
5
/**
6
 * A Time is a fragmented representation of a time period of fixed & static
7
 * length (usually solar days). It is an Immutable object.
8
 *
9
 * A Time MAY not be aware of all|some of its fragments, or of its reference's
10
 * period ratio. (usually when it's been built by a parser).
11
 *
12
 * A Time is not aware of the time format it holds, and MUST NOT check for
13
 * internal consistency. It is only a value holder, and calculation has to be
14
 * made by converters, or other components.
15
 */
16
class Time extends AbstractFragmentedDuration
17
{
18
    /**
19
     * Reference period ratio multiplied by 1 000 000 (to keep and integer)
20
     *
21
     * @var integer|null
22
     */
23
    protected $ratio;
24
25
    /**
26
     * Has the fragment been halved (AM would translate in false, PM in true).
27
     * Each fragment can have one.
28
     *
29
     * @var array<boolean|null>
30
     */
31
    protected $halved = [];
32
33
    /**
34
     * Class constructor.
35
     *
36
     * @param array        $fragments
37
     * @param array        $sizes
38
     * @param integer|null $ratio
39
     */
40
    public function __construct(array $fragments = [], array $sizes = [], $ratio = null)
41
    {
42
        parent::__construct($fragments, $sizes);
43
44
        $this->ratio = $ratio;
45
    }
46
47
    /**
48
     * Get time fragment FIXED VALUE, checking if it has been halved or not.
49
     *
50
     * @param integer $i
51
     *
52
     * @return integer|null
53
     */
54
    public function get($i)
55
    {
56
        if (!isset($this->fragments[$i])) {
57
            return null;
58
        }
59
60
        if (
61
            !isset($this->halved[$i])   // not halved
62
            || !$this->fragments[$i]    // not set
63
            || !isset($this->sizes[$i]) // no solvable
64
        ) {
65
            return $this->fragments[$i];
66
        }
67
68
        $half = (int)floor($this->sizes[$i] / 2);
69
70
        $value = $this->fragments[$i];
71
72
        // Special case for g & h formats handling : if value is the same
73
        // as the half, which is not a possible value due to division,
74
        // ti means it is 0
75
        if ($value === $half) {
76
            $value = 0;
77
        }
78
79
        if ($this->halved[$i]) {
80
            $value += $half;
81
        }
82
83
        return $value;
84
    }
85
86
    /**
87
     * Get time fragment minus half of the fragment size, if possible.
88
     * eg: would return 2 out of 14 on a 24 long fragment.
89
     *
90
     * @param integer $i Fragment index
91
     *
92
     * @return integer|null
93
     */
94
    public function getHalved($i)
95
    {
96
        if (!isset($this->fragments[$i])) {
97
            return null;
98
        }
99
100
        if (!isset($this->sizes[$i])) {
101
            return $this->fragments[$i];
102
        }
103
104
        $half = (int)floor($this->sizes[$i] / 2);
105
106
        return $this->fragments[$i] % $half;
107
    }
108
109
    public function canBeHalved($i)
110
    {
111
        if (isset($this->halved[$i])) {
112
            return $this->halved[$i];
113
        }
114
115
        if (
116
            !isset($this->fragments[$i])
117
            || !isset($this->sizes[$i])
118
        ) {
119
            return null;
120
        }
121
122
        $half = (int)floor($this->sizes[$i] / 2);
123
124
        return $this->fragments[$i] >= $half;
125
    }
126
127
    /**
128
     * Gets ratio.
129
     *
130
     * @return integer|null
131
     */
132
    public function getRatio()
133
    {
134
        return $this->ratio;
135
    }
136
137
    /**
138
     * Gets a new instance with input ratio.
139
     *
140
     * @param integer|null $ratio
141
     *
142
     * @return static
143
     */
144
    public function withRatio($ratio)
145
    {
146
        $res = clone $this;
147
        $res->ratio = $ratio;
148
149
        return $res;
150
    }
151
152
    /**
153
     * Checks if a fragment was halved
154
     *
155
     * @param integer $i
156
     *
157
     * @return boolean|null
158
     */
159
    public function isHalved($i)
160
    {
161
        if (isset($this->halved[$i])) {
162
            return $this->halved[$i];
163
        }
164
    }
165
166
    /**
167
     * Get all halved.
168
     *
169
     * @return array<boolean|null>
170
     */
171
    public function allHalved()
172
    {
173
        return $this->halved;
174
    }
175
176
    /**
177
     * Set time fragment "halved", adding null values if needed.
178
     *
179
     * @param integer      $index
180
     * @param boolean|null $value
181
     */
182
    public function withHalved($index, $value)
183
    {
184
        $res = clone $this;
185
186
        $res->halved = $this->insertInList($res->halved, $index, $value);
187
188
        return $res;
189
    }
190
191
    /**
192
     * Set all halved, adding null values if needed.
193
     *
194
     * @param array<bool|null> $halved
195
     *
196
     * @return static a new instance.
197
     */
198
    public function withHalveds(array $halved)
199
    {
200
        $res = clone $this;
201
202
        $this->halved = $this->fillArrayInput($halved, false);
203
204
        return $res;
205
    }
206
}
207