Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
110 / 110
100.00% covered (success)
100.00%
11 / 11
CRAP
100.00% covered (success)
100.00%
1 / 1
DateTime
100.00% covered (success)
100.00%
110 / 110
100.00% covered (success)
100.00%
11 / 11
32
100.00% covered (success)
100.00%
1 / 1
 create
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
 setDefaultDateFormat
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getDefaultDateFormat
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasDefaultDateFormat
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setDefaultTimeFormat
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getDefaultTimeFormat
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasDefaultTimeFormat
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getTotal
100.00% covered (success)
100.00%
28 / 28
100.00% covered (success)
100.00%
1 / 1
8
 getAverage
100.00% covered (success)
100.00%
29 / 29
100.00% covered (success)
100.00%
1 / 1
8
 getWeekDates
100.00% covered (success)
100.00%
32 / 32
100.00% covered (success)
100.00%
1 / 1
4
 __toString
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2/**
3 * Pop PHP Framework (http://www.popphp.org/)
4 *
5 * @link       https://github.com/popphp/popphp-framework
6 * @author     Nick Sagona, III <dev@nolainteractive.com>
7 * @copyright  Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com)
8 * @license    http://www.popphp.org/license     New BSD License
9 */
10
11/**
12 * @namespace
13 */
14namespace Pop\Utils;
15
16use DateTimeZone;
17use DateInterval;
18
19/**
20 * Pop utils date-time helper class
21 *
22 * @category   Pop
23 * @package    Pop\Utils
24 * @author     Nick Sagona, III <dev@nolainteractive.com>
25 * @copyright  Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com)
26 * @license    http://www.popphp.org/license     New BSD License
27 * @version    2.1.0
28 */
29class DateTime extends \DateTime
30{
31
32    use DateTimeTrait;
33
34    /**
35     * Default date format
36     * @var ?string
37     */
38    protected ?string $defaultDateFormat = null;
39
40    /**
41     * Default time format
42     * @var ?string
43     */
44    protected ?string $defaultTimeFormat = null;
45
46    /**
47     * Create a new DateTime object
48     *
49     * @param  string        $dateTime
50     * @param  ?DateTimeZone $timeZone
51     * @param  ?string       $defaultDateFormat
52     * @param  ?string       $defaultTimeFormat
53     * @throws \Exception
54     * @return static
55     */
56    public static function create(
57        string $dateTime = 'now', ?DateTimeZone $timeZone = null,
58        ?string $defaultDateFormat = null, ?string $defaultTimeFormat = null): static
59    {
60        $dt = new static($dateTime, $timeZone);
61        if ($defaultDateFormat !== null) {
62            $dt->setDefaultDateFormat($defaultDateFormat);
63        }
64        if ($defaultTimeFormat !== null) {
65            $dt->setDefaultTimeFormat($defaultTimeFormat);
66        }
67
68        return $dt;
69    }
70
71    /**
72     * Method to set the default date format
73     *
74     * @param  string $defaultDateFormat
75     * @return static
76     */
77    public function setDefaultDateFormat(string $defaultDateFormat): static
78    {
79        $this->defaultDateFormat = $defaultDateFormat;
80        return $this;
81    }
82
83    /**
84     * Method to get the default date format
85     *
86     * @return string
87     */
88    public function getDefaultDateFormat(): string
89    {
90        return $this->defaultDateFormat;
91    }
92
93    /**
94     * Method to see if the object as a default date format
95     *
96     * @return bool
97     */
98    public function hasDefaultDateFormat(): bool
99    {
100        return !empty($this->defaultDateFormat);
101    }
102
103    /**
104     * Method to set the default time format
105     *
106     * @param  string $defaultTimeFormat
107     * @return static
108     */
109    public function setDefaultTimeFormat(string $defaultTimeFormat): static
110    {
111        $this->defaultTimeFormat = $defaultTimeFormat;
112        return $this;
113    }
114
115    /**
116     * Method to get the default time format
117     *
118     * @return string
119     */
120    public function getDefaultTimeFormat(): string
121    {
122        return $this->defaultTimeFormat;
123    }
124
125    /**
126     * Method to see if the object as a default time format
127     *
128     * @return bool
129     */
130    public function hasDefaultTimeFormat(): bool
131    {
132        return !empty($this->defaultTimeFormat);
133    }
134
135    /**
136     * Method to get total time from array of multiple time values in HH:MM:SS format
137     *
138     * Standard hh:mm:ss format string is '%H:%I:%S'
139     *
140     * @param  array $times
141     * @param  ?string $format
142     * @param  bool $secondsOnly
143     * @throws \Exception
144     * @return DateInterval|string
145     */
146    public static function getTotal(array $times, ?string $format = null, bool $secondsOnly = false): DateInterval|string
147    {
148        $totalHours   = 0;
149        $totalMinutes = 0;
150        $totalSeconds = 0;
151
152        foreach ($times as $time) {
153            if ($time instanceof \DateInterval) {
154                $hours   = $time->format('%h');
155                $minutes = $time->format('%i');
156                $seconds = $time->format('%s');
157            } else {
158                if (substr_count($time, ':') == 2) {
159                    [$hours, $minutes, $seconds] = explode(':', $time);
160                } else {
161                    $hours = 0;
162                    [$minutes, $seconds] = explode(':', $time);
163                }
164            }
165            $totalHours   += (int)$hours;
166            $totalMinutes += (int)$minutes;
167            $totalSeconds += (int)$seconds;
168        }
169
170        if ($secondsOnly) {
171            $totalSeconds  += (int)$totalHours * 3600;
172            $totalSeconds  += (int)$totalMinutes * 60;
173            $intervalFormat = 'PT' . $totalSeconds . 'S';
174        } else {
175            if ($totalSeconds > 60) {
176                $totalMinutes += floor($totalSeconds / 60);
177                $totalSeconds  = $totalSeconds % 60;
178            }
179            if ($totalMinutes > 60) {
180                $totalHours  += floor($totalMinutes / 60);
181                $totalMinutes = $totalMinutes % 60;
182            }
183            $intervalFormat = 'PT' . (int)$totalHours . 'H' . (int)$totalMinutes . 'M' . (int)$totalSeconds . 'S';
184        }
185
186        $dateInterval = new DateInterval($intervalFormat);
187
188        return ($format !== null) ? $dateInterval->format($format) : $dateInterval;
189    }
190
191    /**
192     * Method to get average time from array of multiple time values in HH:MM:SS format
193     *
194     * Standard hh:mm:ss format string is '%H:%I:%S'
195     *
196     * @param  array   $times
197     * @param  ?string $format
198     * @param  bool    $secondsOnly
199     * @throws \Exception
200     * @return DateInterval|string
201     */
202    public static function getAverage(array $times, ?string $format = null, bool $secondsOnly = false): DateInterval|string
203    {
204        $total       = static::getTotal($times, null, true);
205        $totalTime   = $total->s;
206        $averageTime = round(($totalTime / count($times)), 2);
207        $hh          = 0;
208        $mm          = 0;
209        $ss          = 0;
210
211        if ($averageTime >= 3600) {
212            $hh   = floor($averageTime / 3600);
213            $mins = $averageTime - ($hh * 3600);
214            $mm   = floor($mins / 60);
215            $ss   = (int)($mins - ($mm * 60)) % 60;
216        } else if ($averageTime >= 60) {
217            $mm = floor($averageTime / 60);
218            $ss = ((int)$averageTime % 60);
219        } else {
220            $ss = $averageTime;
221        }
222
223        if ($secondsOnly) {
224            $totalSeconds   = 0;
225            $totalSeconds  += (int)$hh * 3600;
226            $totalSeconds  += (int)$mm * 60;
227            $intervalFormat = 'PT' . $totalSeconds . 'S';
228        } else {
229            $intervalFormat = 'PT';
230            if ($hh != 0) {
231                $intervalFormat .= (int)$hh . 'H';
232            }
233            if ($mm != 0) {
234                $intervalFormat .= (int)$mm . 'M';
235            }
236            if ($ss != 0) {
237                $intervalFormat .= (int)$ss . 'S';
238            }
239        }
240
241        $dateInterval = new DateInterval($intervalFormat);
242
243        return ($format !== null) ? $dateInterval->format($format) : $dateInterval;
244    }
245
246    /**
247     * Method to get dates of a week
248     *
249     * @param  ?int    $week
250     * @param  ?int    $year
251     * @param  ?string $format
252     * @return array
253     */
254    public static function getWeekDates(?int $week = null, ?int $year = null, ?string $format = null): array
255    {
256        if ($week === null) {
257            $week = date('W');
258        }
259        if ($year === null) {
260            $year = date('Y');
261        }
262
263        $today     = new static('today');
264        $sunday    = clone $today->setISODate($year, $week, 0);
265        $monday    = clone $today->setISODate($year, $week, 1);
266        $tuesday   = clone $today->setISODate($year, $week, 2);
267        $wednesday = clone $today->setISODate($year, $week, 3);
268        $thursday  = clone $today->setISODate($year, $week, 4);
269        $friday    = clone $today->setISODate($year, $week, 5);
270        $saturday  = clone $today->setISODate($year, $week, 6);
271
272        if ($format !== null) {
273            $weekDates = [
274                0 => $sunday->format($format),
275                1 => $monday->format($format),
276                2 => $tuesday->format($format),
277                3 => $wednesday->format($format),
278                4 => $thursday->format($format),
279                5 => $friday->format($format),
280                6 => $saturday->format($format),
281            ];
282        } else {
283            $weekDates = [
284                0 => $sunday,
285                1 => $monday,
286                2 => $tuesday,
287                3 => $wednesday,
288                4 => $thursday,
289                5 => $friday,
290                6 => $saturday,
291            ];
292        }
293
294        return $weekDates;
295    }
296
297    /**
298     * __toString method
299     *
300     * @return string
301     */
302    public function __toString(): string
303    {
304        $string = '';
305
306        if (!empty($this->defaultDateFormat)) {
307            $format = $this->defaultDateFormat;
308
309            if (!empty($this->defaultTimeFormat)) {
310                $format .= ' ' . $this->defaultTimeFormat;
311            }
312
313            $string = $this->format($format);
314        }
315
316        return $string;
317    }
318
319}
320