Issues (1)

src/ArithmeticDates.php (1 issue)

Severity
1
<?php
2
3
namespace Dates\Manejos;
4
5
use DateTime;
6
use InvalidArgumentException;
7
8
/**
9
 * Es una clase que maneja fechas de forma facil
10
 *
11
 * Para usuarla hay dos parametros opcionales
12
 * datetime que si no ingresa una fecha en formato string
13
 * y no ingresa nada regresa la fecha actual
14
 * el segundo parametro es la zono horaria si no ingresa una
15
 * zona horaria que soporte PHP se ejecutara con la zona horaria
16
 * por defecto del servidor zonas horarias soportadas por PHP @link<https://www.php.net/manual/es/timezones.php>
17
 * revise su continente y luego escoga su continente y luego su cuidad y agreguelo como segundo argumento
18
 * o a partir de PHP 8 puede agregar ese unico argumento como zoneHoraria:"America/Guayaquil"
19
 *
20
 *
21
 * PHP version ^8.1
22
 *
23
 * @author Dorian Armijos
24
 * @link <>
25
 * @category Dates
26
 * @return DateTime
27
 */
28
29
class ArithmeticDates extends \DateTime
30
{
31
    /**
32
     * @var datetime
33
     */
34
    private $datetime;
35
    private $day;
36
    private $hours;
37
    private $minute;
38
    private $seconds;
39
    private $microseconds;
40
    private $year;
41
    private $mounth;
42
    private $message;
43
    private const REG_E = "/^([0-9]{4}\b)-([0][1-9]{1}\b|[1][0-2]{1}\b)-([0][1-9]{1}\b|[1-2][0-9]{1}\b|[3][0-1]{1}\b)/";
44
    /**
45
     *
46
     */
47 3
    public function __construct(string $datetime = 'now', string $zoneHoraria = null)
48
    {
49
        /**
50
         * Los siguientes if realizar la tarea de identificar que sea una fecha valida
51
         */
52
53 3
        if (strtolower($datetime) != 'now' && !preg_match(self::REG_E, $datetime)) {
54
            throw new InvalidArgumentException('Error no ingreso una fecha correcta');
55
        }
56
        /**
57
         * Verifica que tenga agregada una zona horaria
58
         */
59 3
        if ($zoneHoraria) {
60 3
                date_default_timezone_set($zoneHoraria);
61
        }
62
63 3
        $this->datetime = new \DateTime($datetime);
64 3
        parent::__construct($this->datetime->format('Y-m-d H:i:s'));
65 3
        $this->day          = $this->datetime->format('d');
66 3
        $this->hours        = $this->datetime->format('H');
67 3
        $this->minute       = $this->datetime->format('i');
68 3
        $this->seconds      = $this->datetime->format('s');
69 3
        $this->microseconds = $this->datetime->format('u');
70 3
        $this->year         = $this->datetime->format('Y');
71 3
        $this->mounth       = $this->datetime->format('m');
72
    }
73
    /**
74
     * Este metodo permite aumentar los meses de la fecha actual
75
     *
76
     * @param int $numberMoth Es un entero que aumenta a la fecha el numero de meses  este valor no puede ser > 12 o < 0
77
     */
78
    public function setMoth(int $numberMoth): void
79
    {
80
        if ($numberMoth > 12) {
81
            $this->message = 'Desborda el numero de meses permitidos';
82
            throw new InvalidArgumentException($this->message);
83
        }
84
        if ($numberMoth < 0) {
85
            $this->message = 'Error no se puede aumentar meses negativos' ;
86
            throw new InvalidArgumentException($this->message);
87
        }
88
89
        $mounthChange = intval($this->mounth, 10);
90
        $calculo = $mounthChange + $numberMoth;
91
        $moreYear = $this->year;
92
        $moreMounth = $calculo;
93
        if ($calculo > 12) {
94
            $this->setYear(1);
95
            $moreYear = $this->year;
96
            $moreMounth = $calculo - 12;
97
        }
98
        if ($moreMounth < 10) {
99
            $moreMounth = '0' . $moreMounth;
100
        }
101
        $dateFormat = $moreYear . '-' . $moreMounth . '-' . $this->day . ' ';
102
        $timeFormat = $this->hours . ':' . $this->minute . ':' . $this->seconds . '.' . $this->microseconds;
103
        $formatDate =  $dateFormat . $timeFormat;
104
        $this->year = $moreYear;
105
        $this->mounth = $moreMounth;
106
        $this->datetime = new \DateTime($formatDate);
107
    }
108
109
    /**
110
     * Este metodo permite aumentar los años a la fecha actual
111
     *
112
     * @param int $year aumenta en años la fecha actual
113
     * @return void
114
     */
115
116
    public function setYear(int $year)
117
    {
118
        if ($year < 0) {
119
            $this->message = 'Error no se puede aumentar años negativos';
120
            throw new InvalidArgumentException($this->message);
121
        }
122
        $this->year = intval($this->year, 10) + $year;
123
        $dateFormat = $this->year . '-' . $this->mounth . '-' . $this->day . ' ';
124
        $timeFormat = $this->hours . ':' . $this->minute . ':' . $this->seconds . '.' . $this->microseconds;
125
        $formatDate =  $dateFormat . $timeFormat;
126
        $this->datetime = new \DateTime($formatDate);
127
    }
128
129
    /**
130
     * Este metodo sirve para aumentar los dias de la fecha
131
     *
132
     * @param int $day Son los dias que puede aumentar a la fecha este valor no puede ser > 31 o < 0
133
     * @return void
134
     */
135
136
    public function setDay(int $day): void
137
    {
138
        if ($day > 31 || $day < 0) {
139
            $this->message = 'Error el valor no puede ser mayor a 31 o menor a 0';
140
            throw new InvalidArgumentException($this->message);
141
        }
142
        $numberDays = $this->getMothDay($this->mounth);
143
        $daysCalculo = intval($this->day) + $day;
144
        $moreDays = $daysCalculo;
145
        $moreMounth = $this->mounth;
146
        if ($daysCalculo > $numberDays) {
147
            $this->setMoth(1);
148
            $moreMounth = $this->mounth;
149
            $daysmorMount = $this->getMothDay($moreMounth);
150
            if ($daysCalculo > $daysmorMount) {
151
                $this->setMoth(1);
152
                $moreMounth = $this->mounth;
153
                $moreDays = $daysCalculo - $daysmorMount;
154
            } else {
155
                $moreDays = $daysmorMount - $daysCalculo;
156
            }
157
        }
158
159
        if ($moreDays < 10) {
160
            $moreDays = '0' . $moreDays;
161
        }
162
        $dateFormat = $this->year . '-' . $moreMounth . '-' . $moreDays . ' ';
163
        $timeFormat = $this->hours . ':' . $this->minute . ':' . $this->seconds . '.' . $this->microseconds;
164
        $formatDate =  $dateFormat . $timeFormat;
165
        $this->datetime = new \DateTime($formatDate);
166
        $this->mounth = $moreMounth;
167
        $this->day = $moreDays;
168
    }
169
170
171
    /**
172
     * Este metodo permite aumenta a la fecha las horas los minutos y los segundos
173
     *
174
     * @param int $hours Son las horas que se aumneta a la fecha el valor no puede ser > 24 y < 0
175
     * @param int $minutes Son los minutos que se aumenta a la fecha el valor no puede ser > 60 y < 0
176
     * @param int $seconds Son los segundos que se aumenta a la fecha el valor no puede ser > 60 y < 0
177
     * @return void
178
     */
179 1
    public function setHourMinutesSeconds(int $hours, int $minutes, int $seconds = 00): void
180
    {
181 1
        if ($hours > 24 || $hours < 0) {
182
            $this->message = 'Error las horas no deben sobrepasar el valor de 24 o menor a 0';
183
            throw new InvalidArgumentException($this->message);
184
        }
185 1
        if ($minutes > 60 || $minutes < 0) {
186
            $this->message = 'Error los minitos no deben sobrepasar los 60 o ser menores a 0';
187
            throw new InvalidArgumentException($this->message);
188
        }
189 1
        if ($seconds > 60 || $seconds < 0) {
190
            $this->message = 'Error los segundos no deben sobrepasar los 60 o ser menores a 0';
191
            throw new InvalidArgumentException();
192
        }
193
194 1
        $hoursCalculo = intval($this->hours) + $hours;
195 1
        $minutesCalculo = intval($this->minute) + $minutes;
196 1
        $secondsCalculo = $seconds;
197 1
        if ($seconds > 0) {
198
            $secondsCalculo = intval($this->seconds) + $seconds;
199
        }
200
        /**
201
         * Calculamos las horas
202
         * Calculamos los minitos
203
         * Calculamos los segundos
204
         */
205 1
        $moreHours = $hoursCalculo;
0 ignored issues
show
The assignment to $moreHours is dead and can be removed.
Loading history...
206 1
        $moreMinites = $minutesCalculo;
207 1
        $moreSeconds = $secondsCalculo;
208
209 1
        if ($secondsCalculo > 60) {
210
            $minutesCalculo += 1;
211
            $moreSeconds = $secondsCalculo - 60;
212
        }
213 1
        if ($moreSeconds < 9) {
214 1
            $moreSeconds = '0' . $moreSeconds;
215
        }
216
217 1
        if ($minutesCalculo > 60) {
218
            $hoursCalculo += 1;
219
            $moreMinites = $minutesCalculo - 60;
220
        }
221 1
        if ($moreMinites < 9) {
222 1
            $moreMinites = '0' . $moreMinites;
223
        }
224
225 1
        $moreDays = $this->day;
226 1
        if ($hoursCalculo > 24) {
227
            $this->setDay(1);
228
            $moreDays = $this->day;
229
            $moreHours = $hoursCalculo - 24;
230
        }
231 1
        $moreHours = $hoursCalculo;
232 1
        if ($moreHours < 9) {
233
            $moreHours = '0' . $moreHours;
234
        }
235 1
        if (intval($moreMinites) == 60 && intval($moreSeconds) == 00) {
236
            $moreMinites = '59';
237
            $moreSeconds = '60';
238
        }
239 1
        $dateFormat = $this->year . '-' . $this->mounth . '-' . $moreDays . ' ';
240 1
        $timeFormat = $moreHours . ':'  . $moreMinites . ':' . $moreSeconds;
241 1
        $formatDate = $dateFormat . $timeFormat;
242 1
        $this->datetime = new \DateTime($formatDate);
243 1
        $this->day = $moreDays;
244 1
        $this->hours = $moreHours;
245 1
        $this->minute = $moreMinites;
246 1
        $this->seconds = $moreSeconds;
247
    }
248
249
    /**
250
     * Permite encontrar cuantos dias tiene el mes a umentar
251
     *
252
     * @param string $indexMounth Es el indece del mes que regresa el numero de dias que tiene
253
     * @return int
254
     */
255
    private function getMothDay(string $indexMounth): int
256
    {
257
        $mounthDays = [31,28,31,30,31,30,31,31,30,31,30,31];
258
        if ($this->leapYear()) {
259
            $mounthDays = [31,29,31,30,31,30,31,31,30,31,30,31];
260
        }
261
262
        return $mounthDays[intval($indexMounth) - 1];
263
    }
264
    /**
265
     * Metodo para saber si una año es bisiesto y es febrero
266
     *
267
     * @return bool
268
     */
269
270
    private function leapYear(): bool
271
    {
272
        return date('L', strtotime($this->datetime->format('Y-m-d'))) &&  intval($this->mounth) == 2 ;
273
    }
274
    /**
275
     * Esta funcion regresa el resultado final de haber aplicado los metodos
276
     *
277
     *  @return DateTime|ArithmeticDates
278
     */
279 1
    public function getResult(): DateTime|ArithmeticDates
280
    {
281 1
        return $this->datetime;
282
    }
283
284
    /**
285
     * Este metodo estatico permite verificar si una fecha en especifo se encentra dentro de un rango de fechas
286
     *
287
     * @param DateTime|ArithmeticDates $start Es el intervalo inicial
288
     * @param DateTime|ArithmeticDates $end Es el intervalo final
289
     * @param DateTime|ArithmeticDates $date Es la fecha a comprobar si se encuentra en ese intervalo de $start a $end
290
     * @return bool
291
     */
292
293 1
    public static function hasInterval(
294
        DateTime|ArithmeticDates $start,
295
        DateTime|ArithmeticDates $end,
296
        DateTime|ArithmeticDates $date
297
    ): bool
298
    {
299 1
        $startInterval = $start->getTimestamp();
300 1
        $endInterval = $end->getTimestamp();
301
302 1
        return $date->getTimestamp() >= $startInterval && $date->getTimestamp() <= $endInterval;
303
    }
304
}
305