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