GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

string_time_elapsed()   B
last analyzed

Complexity

Conditions 9
Paths 96

Size

Total Lines 38
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 9
eloc 25
nc 96
nop 2
dl 0
loc 38
rs 8.0555
c 1
b 0
f 0
1
<?php
2
/**
3
 * This file is part of the O2System Framework package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 *
8
 * @author         Steeve Andrian Salim
9
 * @copyright      Copyright (c) Steeve Andrian Salim
10
 */
11
// ------------------------------------------------------------------------
12
13
if ( ! function_exists('timestamp')) {
14
    /**
15
     * timestamp
16
     *
17
     * SQL Timestamp
18
     *
19
     * @param int|string $timestamp
20
     *
21
     * @return string
22
     * @throws \Exception
23
     */
24
    function timestamp($timestamp = null)
25
    {
26
        if ( ! isset($timestamp) OR $timestamp === 'NOW') {
27
            $timestamp = now();
28
        } elseif (is_string($timestamp)) {
29
            $timestamp = strtotime($timestamp);
30
        }
31
32
        return date('Y-m-d H:i:s', $timestamp);
33
    }
34
}
35
// ------------------------------------------------------------------------
36
37
if ( ! function_exists('unix_timestamp')) {
38
    /**
39
     * unix_timestamp
40
     *
41
     * SQL Unix Timestamp
42
     *
43
     * @param int|string $timestamp
44
     *
45
     * @return string
46
     * @throws \Exception
47
     */
48
    function unix_timestamp($timestamp = null)
49
    {
50
        if ( ! isset($timestamp) OR $timestamp === 'NOW') {
51
            return now();
52
        } elseif (is_string($timestamp)) {
53
            return strtotime($timestamp);
54
        } elseif (is_numeric($timestamp)) {
0 ignored issues
show
introduced by
The condition is_numeric($timestamp) is always true.
Loading history...
55
            return $timestamp;
56
        }
57
58
        return now();
59
    }
60
}
61
62
// ------------------------------------------------------------------------
63
64
if ( ! function_exists('format_date')) {
65
    /**
66
     * format_date
67
     *
68
     * Returns string of day, date time or else, depend on type setting, with custom date separator and multi language
69
     * support
70
     *
71
     * @param int|string $timestamp
72
     * @param string     $format
73
     *
74
     * @return  string
75
     * @throws \Exception
76
     */
77
    function format_date($timestamp = null, $format = '%l, %d-%F-%Y %h:%i:%s %a')
78
    {
79
        $timestamp = (is_null($timestamp)
80
            ? now()
81
            : (is_numeric($timestamp)
82
                ? $timestamp
83
                : strtotime(
84
                    $timestamp
85
                )));
86
        $date = parse_date($timestamp);
87
88
        $output = $format;
89
90
        foreach ($date as $replace => $value) {
91
            $output = str_ireplace('%' . $replace, $value, $output);
92
        }
93
94
        return $output;
95
    }
96
}
97
// ------------------------------------------------------------------------
98
99
if ( ! function_exists('parse_date')) {
100
    /**
101
     * parse_date
102
     *
103
     * Parse Date into Array
104
     *
105
     * Simple function to take in a date format and return array of associated formats for each date element
106
     *
107
     * @param int|string $timestamp
108
     *
109
     * @return \O2System\Spl\DataStructures\SplArrayObject
110
     * @throws \Exception
111
     */
112
    function parse_date($timestamp = null)
113
    {
114
        $timestamp = (is_null($timestamp)
115
            ? now()
116
            : (is_numeric($timestamp)
117
                ? $timestamp
118
                : strtotime(
119
                    $timestamp
120
                )));
121
        $date_parts = new \O2System\Spl\DataStructures\SplArrayObject(
122
            [
123
                't'  => $timestamp,
124
                'd'  => date('d', $timestamp),
0 ignored issues
show
Bug introduced by
It seems like $timestamp can also be of type string; however, parameter $timestamp of date() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

124
                'd'  => date('d', /** @scrutinizer ignore-type */ $timestamp),
Loading history...
125
                'D'  => date('D', $timestamp),
126
                'Y'  => date('Y', $timestamp),
127
                'y'  => date('y', $timestamp),
128
                'am' => time_meridiem($timestamp),
129
                'a'  => date('a', $timestamp),
130
                'h'  => date('h', $timestamp),
131
                'H'  => date('H', $timestamp),
132
                'i'  => date('i', $timestamp),
133
                's'  => date('s', $timestamp),
134
                'w'  => date('w', $timestamp),
135
                'l'  => day_name($timestamp, 'l'),
136
                'm'  => date('m', $timestamp),
137
                'n'  => date('n', $timestamp),
138
                'F'  => month_name($timestamp, 'F'),
139
                'M'  => month_name($timestamp, 'M'),
140
                'e'  => string_time_elapsed($timestamp),
141
            ]
142
        );
143
144
        return $date_parts;
145
    }
146
}
147
// ------------------------------------------------------------------------
148
149
if ( ! function_exists('day_name')) {
150
    /**
151
     * day_name
152
     *
153
     * Day Name in Languages
154
     *
155
     * @param int|string $timestamp
156
     * @param string     $type
157
     *
158
     * @return array
159
     * @throws \Exception
160
     */
161
    function day_name($timestamp = null, $type = 'D')
162
    {
163
        $timestamp = (is_null($timestamp)
164
            ? now()
165
            : (is_numeric($timestamp)
166
                ? $timestamp
167
                : strtotime(
168
                    $timestamp
169
                )));
170
171
        language()->loadFile('calendar');
172
173
        return language()->getLine(strtoupper('CAL_' . date($type, $timestamp)));
0 ignored issues
show
Bug introduced by
It seems like $timestamp can also be of type string; however, parameter $timestamp of date() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

173
        return language()->getLine(strtoupper('CAL_' . date($type, /** @scrutinizer ignore-type */ $timestamp)));
Loading history...
174
    }
175
}
176
// ------------------------------------------------------------------------
177
178
if ( ! function_exists('month_name')) {
179
    /**
180
     * month_name
181
     *
182
     * Month Name in Languages
183
     *
184
     * @param int|string $timestamp
185
     * @param string     $type
186
     *
187
     * @return string
188
     * @throws \Exception
189
     */
190
    function month_name($timestamp = null, $type = 'M')
191
    {
192
        $timestamp = (is_null($timestamp)
193
            ? now()
194
            : (is_numeric($timestamp)
195
                ? $timestamp
196
                : strtotime(
197
                    $timestamp
198
                )));
199
        language()->loadFile('calendar');
200
201
        return language()->getLine(strtoupper('CAL_' . date($type, $timestamp)));
0 ignored issues
show
Bug introduced by
It seems like $timestamp can also be of type string; however, parameter $timestamp of date() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

201
        return language()->getLine(strtoupper('CAL_' . date($type, /** @scrutinizer ignore-type */ $timestamp)));
Loading history...
202
    }
203
}
204
// ------------------------------------------------------------------------
205
206
if ( ! function_exists('time_meridiem')) {
207
    /**
208
     * part_time
209
     *
210
     * Part Time in Languages
211
     *
212
     * @param int|string $timestamp
213
     *
214
     * @return string
215
     * @throws \Exception
216
     */
217
    function time_meridiem($timestamp = null)
218
    {
219
        $timestamp = (is_null($timestamp)
220
            ? now()
221
            : (is_numeric($timestamp)
222
                ? $timestamp
223
                : strtotime(
224
                    $timestamp
225
                )));
226
        $part_time_number = date('G', $timestamp);
0 ignored issues
show
Bug introduced by
It seems like $timestamp can also be of type string; however, parameter $timestamp of date() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

226
        $part_time_number = date('G', /** @scrutinizer ignore-type */ $timestamp);
Loading history...
227
        language()->loadFile('date');
228
229
        if ($part_time_number >= 5 AND $part_time_number < 11) {
230
            return language()->getLine('DATE_MORNING');
231
        } elseif ($part_time_number >= 11 AND $part_time_number < 15) {
232
            return language()->getLine('DATE_MORNING');
233
        } elseif ($part_time_number >= 15 AND $part_time_number < 18) {
234
            return language()->getLine('DATE_DAYTIME');
235
        } elseif ($part_time_number >= 18 AND $part_time_number < 19) {
236
            return language()->getLine('DATE_AFTERNOON');
237
        } elseif ($part_time_number >= 19 AND $part_time_number < 24) {
238
            return language()->getLine('DATE_NIGHT');
239
        } elseif ($part_time_number >= 24 AND $part_time_number < 5) {
240
            return language()->getLine('DATE_MIDNIGHT');
241
        }
242
    }
243
}
244
// ------------------------------------------------------------------------
245
246
if ( ! function_exists('string_time_elapsed')) {
247
    /**
248
     * string_time_elapsed
249
     *
250
     * Day Date Time in String Format
251
     *
252
     * Returns String of Day date time
253
     *
254
     * @param   int|string $time Time
255
     * @param   bool       $full Full String
256
     *
257
     * @return  string
258
     * @throws \Exception
259
     */
260
    function string_time_elapsed($time = null, $full = false)
261
    {
262
        language()->loadFile('date');
263
264
        $time = is_null($time) ? now() : $time;
265
        $time = is_numeric($time) ? $time : strtotime($time);
266
267
        $now = new DateTime;
268
        $ago = new DateTime(date('r', $time));
0 ignored issues
show
Bug introduced by
It seems like $time can also be of type string; however, parameter $timestamp of date() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

268
        $ago = new DateTime(date('r', /** @scrutinizer ignore-type */ $time));
Loading history...
269
        $diff = $now->diff($ago);
270
271
        $diff->w = floor($diff->d / 7);
0 ignored issues
show
Bug introduced by
The property w does not seem to exist on DateInterval.
Loading history...
272
        $diff->d -= $diff->w * 7;
273
274
        $string = [
275
            'y' => language()->getLine('DATE_YEAR'),
276
            'm' => language()->getLine('DATE_MONTH'),
277
            'w' => language()->getLine('DATE_WEEK'),
278
            'd' => language()->getLine('DATE_DAY'),
279
            'h' => language()->getLine('DATE_HOUR'),
280
            'i' => language()->getLine('DATE_MINUTE'),
281
            's' => language()->getLine('DATE_SECOND'),
282
        ];
283
284
        foreach ($string as $key => &$value) {
285
            if ($diff->$key) {
286
                $value = $diff->$key . ' ' . $value . ($diff->$key > 1 && language()->getDefaultLocale() === 'en' ? 's' : '');
287
            } else {
288
                unset($string[ $key ]);
289
            }
290
        }
291
292
        if ( ! $full) {
293
            $string = array_slice($string, 0, 1);
294
        }
295
296
        return $string ? implode(', ',
297
                $string) . ' ' . language()->getLine('DATE_AGO') : language()->getLine('DATE_JUST_NOW');
298
299
    }
300
}
301
302
// ------------------------------------------------------------------------
303
304
if ( ! function_exists('dates_between')) {
305
    /**
306
     * dates_between
307
     *
308
     * Here is a simple function that gets all the dates between 2 given dates and returns an array (including the dates
309
     * specified)
310
     *
311
     * @example
312
     * dates_between('2001-12-28', '2002-01-01');
313
     *
314
     * @param   int|string $start_date Start Date
315
     * @param   int|string $end_date   End Date
316
     *
317
     * @return  array
318
     */
319
    function dates_between($start_date, $end_date, $format = 'Y-m-d')
320
    {
321
        $day = 60 * 60 * 24;
322
        $start_date = (! is_numeric($start_date) ? strtotime($start_date) : $start_date);
323
        $end_date = (! is_numeric($end_date) ? strtotime($end_date) : $end_date);
324
325
        $days_diff = round(
326
            ($end_date - $start_date) / $day
327
        ); // Unix time difference devided by 1 day to get total days in between
328
329
        $dates_array = [];
330
331
        if ($format == 'time') {
332
            $dates_array[] = $start_date;
333
        } else {
334
            $dates_array[] = date($format, $start_date);
0 ignored issues
show
Bug introduced by
It seems like $start_date can also be of type string; however, parameter $timestamp of date() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

334
            $dates_array[] = date($format, /** @scrutinizer ignore-type */ $start_date);
Loading history...
335
        }
336
337
        for ($x = 1; $x < $days_diff; $x++) {
338
            if ($format == 'time') {
339
                $dates_array[] = $start_date + ($day * $x);
340
            } else {
341
                $dates_array[] = date($format, ($start_date + ($day * $x)));
342
            }
343
        }
344
345
        if ($format == 'time') {
346
            $dates_array[] = $end_date;
347
        } else {
348
            $dates_array[] = date($format, $end_date);
349
        }
350
351
        return $dates_array;
352
    }
353
}
354
355
// ------------------------------------------------------------------------
356
357
if ( ! function_exists('time_range')) {
358
    /**
359
     * time_range
360
     *
361
     * Returns Array of Time Range Options in 15 Minutes Step
362
     *
363
     * @param   int $mode 12|24 Hour Mode
364
     * @param   int $step Minutes Step
365
     *
366
     * @return  array
367
     */
368
    function time_range($mode = 24, $step = 15)
369
    {
370
        $time = [];
371
        $minutes = range(0, (60 - $step), $step);
372
        for ($i = 0; $i <= 23; $i++) {
373
            $hour = (strlen($i) == 1 ? '0' . $i : $i);
374
            foreach ($minutes as $minute) {
375
                $hours = $hour . ':' . (strlen($minute) == 1 ? '0' . $minute : $minute);
376
                $time_12 = date("h:i a", strtotime($hours));
377
                $time_24 = $hours;
378
                if ($mode == 12) {
379
                    $time[ $time_12 ] = $time_12;
380
                } elseif ($mode == 24) {
381
                    $time[ $time_24 ] = $time_24;
382
                }
383
            }
384
        }
385
386
        return $time;
387
    }
388
}
389
390
// ------------------------------------------------------------------------
391
392
if ( ! function_exists('calculate_days')) {
393
    /**
394
     * calculate_days
395
     *
396
     * Returns amount of weeks
397
     *
398
     * @param   int|string $start_date Start Date
399
     * @param   int|string $end_date   End Date
400
     * @param   string     $hour       Hour
401
     *
402
     * @return  int
403
     */
404
    function calculate_days($start_date, $end_date, $hour = '12:00:00 am')
405
    {
406
        $start_date = (is_numeric($start_date) ? date('d-m-Y', $start_date) : $start_date);
0 ignored issues
show
Bug introduced by
It seems like $start_date can also be of type string; however, parameter $timestamp of date() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

406
        $start_date = (is_numeric($start_date) ? date('d-m-Y', /** @scrutinizer ignore-type */ $start_date) : $start_date);
Loading history...
407
        $end_date = (is_numeric($end_date) ? date('d-m-Y', $end_date) : $end_date);
408
        $hour = (is_numeric($hour) ? date('h:i:s a', $hour) : $hour);
409
410
        $start_date = $start_date . ' ' . $hour;
411
        $end_date = $end_date . ' ' . $hour;
412
413
        $start_date = strtotime($start_date);
414
        $end_date = strtotime($end_date);
415
416
        $hours = 24 * 60 * 60; // Hours in a day
417
        $time = $end_date - $start_date;
418
419
        return round($time / $hours);
420
    }
421
}
422
// ------------------------------------------------------------------------
423
424
if ( ! function_exists('calculate_weeks')) {
425
    /**
426
     * calculate_weeks
427
     *
428
     * Returns amount of weeks
429
     *
430
     * @param   int|string $start_date Start Date
431
     * @param   int|string $end_date   End Date
432
     * @param   string     $hour       Hour
433
     *
434
     * @return  int
435
     */
436
    function calculate_weeks($start_date, $end_date, $hour = '12:00:00 am')
437
    {
438
        $start_date = (is_numeric($start_date) ? date('d-m-Y', $start_date) : $start_date);
0 ignored issues
show
Bug introduced by
It seems like $start_date can also be of type string; however, parameter $timestamp of date() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

438
        $start_date = (is_numeric($start_date) ? date('d-m-Y', /** @scrutinizer ignore-type */ $start_date) : $start_date);
Loading history...
439
        $end_date = (is_numeric($end_date) ? date('d-m-Y', $end_date) : $end_date);
440
        $hour = (is_numeric($hour) ? date('h:i:s a', $hour) : $hour);
441
442
        $start_date = $start_date . ' ' . $hour;
443
        $end_date = $end_date . ' ' . $hour;
444
445
        $start_date = strtotime($start_date);
446
        $end_date = strtotime($end_date);
447
448
        $hours = 24 * 60 * 60 * 7; // Hours in a day
449
        $time = $end_date - $start_date;
450
451
        return floor($time / $hours);
452
    }
453
}
454
// ------------------------------------------------------------------------
455
456
if ( ! function_exists('is_weekend')) {
457
    /**
458
     * is_weekend
459
     *
460
     * Validate is the date is a weekend
461
     *
462
     * @param   int|string $date Date
463
     *
464
     * @return  bool
465
     */
466
    function is_weekend($date)
467
    {
468
        $date = (! is_numeric($date) ? strtotime(str_replace('/', '-', $date)) : $date);
469
        $date = date('D', $date);
0 ignored issues
show
Bug introduced by
It seems like $date can also be of type string; however, parameter $timestamp of date() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

469
        $date = date('D', /** @scrutinizer ignore-type */ $date);
Loading history...
470
471
        if ($date == 'Sat' OR $date == 'Sun') {
472
            return true;
473
        }
474
475
        return false;
476
    }
477
}
478
// ------------------------------------------------------------------------
479
480
if ( ! function_exists('is_weekday')) {
481
    /**
482
     * is_weekday
483
     *
484
     * Validate is the date is a week day
485
     *
486
     * @param   int|string $date Date
487
     *
488
     * @return  bool
489
     */
490
    function is_weekday($date)
491
    {
492
        $date = (! is_numeric($date) ? strtotime(str_replace('/', '-', $date)) : $date);
493
        $date = date('D', $date);
0 ignored issues
show
Bug introduced by
It seems like $date can also be of type string; however, parameter $timestamp of date() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

493
        $date = date('D', /** @scrutinizer ignore-type */ $date);
Loading history...
494
495
        if ( ! in_array($date, ['Sat', 'Sun'])) {
496
            return true;
497
        }
498
499
        return false;
500
    }
501
}
502
// ------------------------------------------------------------------------
503
504
if ( ! function_exists('get_age')) {
505
    /**
506
     * get_age
507
     *
508
     * Gets the age of an individual
509
     *
510
     * @param int|string $birthday
511
     * @param string     $return Return value days|months|years
512
     *
513
     * @return int
514
     * @throws \Exception
515
     */
516
    function get_age($birthday, $return = 'years')
517
    {
518
        $birthday = (! is_numeric($birthday) ? strtotime(str_replace('/', '-', $birthday)) : $birthday);
519
520
        $birthday = new DateTime(date('Y-m-d', $birthday));
0 ignored issues
show
Bug introduced by
It seems like $birthday can also be of type string; however, parameter $timestamp of date() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

520
        $birthday = new DateTime(date('Y-m-d', /** @scrutinizer ignore-type */ $birthday));
Loading history...
521
        $now = new DateTime(date('Y-m-d'));
522
        $interval = $birthday->diff($now);
523
524
        $available = [
525
            'years'   => 'y',
526
            'months'  => 'm',
527
            'hours'   => 'h',
528
            'minutes' => 'i',
529
            'seconds' => 's',
530
        ];
531
532
        if (array_key_exists($return, $available)) {
533
            return $interval->{$available[ $return ]};
534
        } elseif (isset($interval->{$return})) {
535
            return $interval->{$return};
536
        }
537
538
        return $interval;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $interval returns the type DateInterval|false which is incompatible with the documented return type integer.
Loading history...
539
    }
540
}
541
// ------------------------------------------------------------------------
542
543
if ( ! function_exists('get_tenure')) {
544
    /**
545
     * get_tenure
546
     *
547
     * Gets tenure from start date and end date
548
     *
549
     * @param int|string      $date_start
550
     * @param int|string|null $date_end
551
     *
552
     * @return string
553
     * @throws \Exception
554
     */
555
    function get_tenure($date_start, $date_end = null)
556
    {
557
        language()->loadFile('date');
558
559
        $date_start = new \DateTime($date_start);
560
561
        if (empty($date_end)) {
562
            $date_end = new \DateTime($date_end);
563
        } else {
564
            $date_end = new DateTime(date('Y-m-d'));
565
        }
566
567
        $dateInterval = $date_start->diff($date_end);
568
569
        return strtolower($dateInterval->format(
570
            '%y ' . language()->getLine('DATE_YEARS') .
571
            ' &mdash; %m ' . language()->getLine('DATE_MONTHS') .
572
            ' &mdash; %d ' . language()->getLine('DATE_DAYS')));
573
    }
574
}
575
576
// ------------------------------------------------------------------------
577
578
if ( ! function_exists('time_breakdown')) {
579
    /**
580
     * time_breakdown
581
     *
582
     * Breakdown a timestamp into an array of days, months, etc since the current time
583
     *
584
     * @param int|string $time
585
     *
586
     * @return array
587
     */
588
    function time_breakdown($time)
589
    {
590
        if ( ! is_numeric($time)) {
591
            $time = strtotime($time);
592
        }
593
        $currentTime = time();
594
        $periods = [
595
            'years'   => 31556926,
596
            'months'  => 2629743,
597
            'weeks'   => 604800,
598
            'days'    => 86400,
599
            'hours'   => 3600,
600
            'minutes' => 60,
601
            'seconds' => 1,
602
        ];
603
        $durations = [
604
            'years'   => 0,
605
            'months'  => 0,
606
            'weeks'   => 0,
607
            'days'    => 0,
608
            'hours'   => 0,
609
            'minutes' => 0,
610
            'seconds' => 0,
611
        ];
612
        if ($time) {
613
            $seconds = $currentTime - $time;
614
            if ($seconds <= 0) {
615
                return $durations;
616
            }
617
            foreach ($periods as $period => $seconds_in_period) {
618
                if ($seconds >= $seconds_in_period) {
619
                    $durations[ $period ] = floor($seconds / $seconds_in_period);
620
                    $seconds -= $durations[ $period ] * $seconds_in_period;
621
                }
622
            }
623
        }
624
625
        return $durations;
626
    }
627
}
628
// ------------------------------------------------------------------------
629
630
if ( ! function_exists('sec2hms')) {
631
    /**
632
     * sec2hms
633
     *
634
     * Convert second to Miliseconds
635
     *
636
     * @param int $num_secs
637
     *
638
     * @return string
639
     */
640
    function sec2hms($num_secs)
641
    {
642
        $str = '';
643
        $hours = intval(intval($num_secs) / 3600);
644
        $str .= $hours . ':';
645
        $minutes = intval(((intval($num_secs) / 60) % 60));
646
        if ($minutes < 10) {
647
            $str .= '0';
648
        }
649
        $str .= $minutes . ':';
650
        $seconds = intval(intval(($num_secs % 60)));
651
        if ($seconds < 10) {
652
            $str .= '0';
653
        }
654
        $str .= $seconds;
655
656
        return $str;
657
    }
658
}
659
// ------------------------------------------------------------------------
660
661
if ( ! function_exists('add_time_duration')) {
662
    /**
663
     * add_time_duration
664
     *
665
     * Add Time Duration
666
     *
667
     * @param int|string $start_time Time or Date
668
     * @param int        $duration
669
     * @param string     $return     Return value|date
670
     *
671
     * @return mixed
672
     */
673
    function add_time_duration($start_time, $duration, $return = 'time')
674
    {
675
        $start_time = (! is_numeric($start_time) ? strtotime($start_time) : $start_time);
676
        $duration = $duration * 60 * 60; // (x) hours * 60 minutes * 60 seconds
677
678
        $add_time = $start_time + $duration;
679
680
        if ($return === 'time') {
681
            return $add_time;
682
        } else {
683
            return format_date($add_time, $return);
684
        }
685
    }
686
}
687
// ------------------------------------------------------------------------
688
689
if ( ! function_exists('calculate_hours')) {
690
    /**
691
     * calculate_hours
692
     *
693
     * Calculate Hours
694
     *
695
     * @param int|string $start_time Time or Date
696
     * @param int|string $end_time   Time or Date
697
     * @param string     $return     Return value time|hours
698
     *
699
     * @return mixed
700
     */
701
    function calculate_hours($start_time, $end_time, $return = 'time')
702
    {
703
        $start_time = (! is_numeric($start_time) ? strtotime($start_time) : $start_time);
704
        $end_time = (! is_numeric($end_time) ? strtotime($end_time) : $end_time);
705
706
        // Times Difference
707
        $difference = $end_time - $start_time;
708
709
        // Hours
710
        $hours = $difference / 3600;
711
712
        // Minutes
713
        $minutes = ($hours - floor($hours)) * 60;
714
715
        $hours = ($minutes != 0 ? $hours - 1 : $hours);
716
717
        // Final
718
        $final_hours = round($hours, 0);
719
        $final_minutes = round($minutes);
720
721
        if ($return === 'time') {
722
            $final_hours = ($final_hours < 10 ? '0' . $final_hours : $final_hours);
723
            $final_minutes = ($final_minutes < 10 ? '0' . $final_minutes : $final_minutes);
724
725
            return $final_hours . ':' . $final_minutes;
726
        } elseif ($return === 'hours') {
727
            return $final_hours + ($final_minutes / 60);
728
        }
729
    }
730
}
731
// ------------------------------------------------------------------------
732
733
if ( ! function_exists('time_difference')) {
734
    /**
735
     * time_difference
736
     *
737
     * Gets the time difference
738
     *
739
     * @param int|string $start_time Time or Date
740
     * @param int|string $end_time   Time or Date
741
     * @param string     $return     Return value array|object
742
     *
743
     * @return mixed
744
     */
745
    function time_difference($start_time, $end_time, $return = 'array')
746
    {
747
        $start_time = (! is_numeric($start_time) ? strtotime($start_time) : $start_time);
748
        $end_time = (! is_numeric($end_time) ? strtotime($end_time) : $end_time);
749
750
        // Times Difference
751
        $difference = $end_time - $start_time;
752
        $result = format_time(abs($difference));
0 ignored issues
show
Bug introduced by
It seems like abs($difference) can also be of type double; however, parameter $seconds of format_time() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

752
        $result = format_time(/** @scrutinizer ignore-type */ abs($difference));
Loading history...
753
754
        if ($return == 'array') {
755
            return $result;
756
        } else {
757
            return implode(':', $result);
0 ignored issues
show
Bug introduced by
$result of type O2System\Spl\DataStructures\SplArrayObject is incompatible with the type array expected by parameter $pieces of implode(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

757
            return implode(':', /** @scrutinizer ignore-type */ $result);
Loading history...
758
        }
759
    }
760
}
761
// ------------------------------------------------------------------------
762
763
if ( ! function_exists('weeks_in_month')) {
764
    /**
765
     * weeks_in_month
766
     *
767
     * Gets num of weeks in a month.
768
     *
769
     * @param int|null $month
770
     * @param int|null $year
771
     *
772
     * @return int
773
     */
774
    function weeks_in_month($month = null, $year = null)
775
    {
776
        // Start Date in Month
777
        $start_date_month = mktime(0, 0, 0, $month, 1, $year);
778
        $start_week_month = (int)date('W', $start_date_month);
779
780
        $amount_day = days_in_month($month, $year);
781
782
        // Finish Date in onth
783
        $finish_date_month = mktime(0, 0, 0, $month, $amount_day, $year);
784
        $finish_week_month = (int)date('W', $finish_date_month);
785
786
        $amount_week = $finish_week_month - $start_week_month + 1;
787
788
        return $amount_week;
789
    }
790
}
791
// ------------------------------------------------------------------------
792
793
if ( ! function_exists('monday_of_week')) {
794
    /**
795
     * monday_of_week
796
     *
797
     * Gets the date of monday of the week.
798
     *
799
     * @param int      $week_number
800
     * @param int|null $year
801
     *
802
     * @return int
803
     */
804
    function monday_of_week($week_number, $year = null)
805
    {
806
        $year = is_null($year) ? date('Y') : $year;
807
808
        $new_year_date = mktime(0, 0, 0, 1, 1, $year);
0 ignored issues
show
Bug introduced by
It seems like $year can also be of type string; however, parameter $year of mktime() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

808
        $new_year_date = mktime(0, 0, 0, 1, 1, /** @scrutinizer ignore-type */ $year);
Loading history...
809
        $first_monday_date = 7 + 1 - date("w", mktime(0, 0, 0, 1, 1, $year));
810
        $dates_from_first_monday = 7 * $week_number;
811
        $second_from_first_monday = 60 * 60 * 24 * ($first_monday_date + $dates_from_first_monday);
812
        $monday_day_of_week = $new_year_date + $second_from_first_monday;
813
        $date_of_monday_day_of_week = 0 + date("j", $monday_day_of_week);
814
815
        return $date_of_monday_day_of_week;
816
    }
817
}
818
// ------------------------------------------------------------------------
819
820
if ( ! function_exists('week_number_of_month')) {
821
    /**
822
     * week_number_of_month
823
     *
824
     * Gets the week Number of a month.
825
     *
826
     * @param int|null $date  Date Number
827
     * @param int|null $month Month Number
828
     * @param int|null $year  Year Number
829
     *
830
     * @return int
831
     */
832
    function week_number_of_month($date = null, $month = null, $year = null)
833
    {
834
        $month = is_null($month) ? date('m') : $month;
835
        $year = is_null($year) ? date('Y') : $year;
836
837
        // Start Date in Month
838
        $start_date_month = mktime(0, 0, 0, $month, 1, $year);
0 ignored issues
show
Bug introduced by
It seems like $month can also be of type string; however, parameter $month of mktime() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

838
        $start_date_month = mktime(0, 0, 0, /** @scrutinizer ignore-type */ $month, 1, $year);
Loading history...
Bug introduced by
It seems like $year can also be of type string; however, parameter $year of mktime() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

838
        $start_date_month = mktime(0, 0, 0, $month, 1, /** @scrutinizer ignore-type */ $year);
Loading history...
839
        $start_week_month = (int)date('W', $start_date_month);
840
841
        // Date Search
842
        $date_search = mktime(0, 0, 0, $month, $date, $year);
843
        $date_week_search = (int)date('W', $date_search);
844
845
        $number_of_week = $date_week_search - $start_week_month + 1;
846
847
        return $number_of_week;
848
    }
849
}
850
// ------------------------------------------------------------------------
851
852
if ( ! function_exists('format_time')) {
853
    /**
854
     * format_time
855
     *
856
     * Format Time from seconds
857
     *
858
     * @param   int $seconds
859
     *
860
     * @return \O2System\Spl\DataStructures\SplArrayObject
861
     */
862
    function format_time($seconds)
863
    {
864
        @$days = floor($seconds / 86400);
865
        if ($days > 0) {
866
            $seconds -= $days * 86400;
867
        }
868
869
        @$years = floor($days / 365);
870
        @$months = floor($days / 30);
871
872
        @$hours = floor($seconds / 3600);
873
        if ($days > 0 || $hours > 0) {
874
            $seconds -= $hours * 3600;
875
        }
876
877
        @$minutes = floor($seconds / 60);
878
        if ($days > 0 || $hours > 0 || $minutes > 0) {
879
            $seconds -= $minutes * 60;
880
        }
881
882
        $format[ 'days' ] = $days;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$format was never initialized. Although not strictly required by PHP, it is generally a good practice to add $format = array(); before regardless.
Loading history...
883
        $format[ 'years' ] = $years;
884
        $format[ 'months' ] = $months;
885
        $format[ 'hours' ] = $hours;
886
        $format[ 'minutes' ] = $minutes;
887
        $format[ 'seconds' ] = $seconds;
888
889
        return new \O2System\Spl\DataStructures\SplArrayObject($format);
890
    }
891
}
892
// ------------------------------------------------------------------------
893
894
/**
895
 * CodeIgniter
896
 *
897
 * An open source application development framework for PHP
898
 *
899
 * This content is released under the MIT License (MIT)
900
 *
901
 * Copyright (c) 2014 - 2015, British Columbia Institute of Technology
902
 *
903
 * Permission is hereby granted, free of charge, to any person obtaining a copy
904
 * of this software and associated documentation files (the "Software"), to deal
905
 * in the Software without restriction, including without limitation the rights
906
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
907
 * copies of the Software, and to permit persons to whom the Software is
908
 * furnished to do so, subject to the following conditions:
909
 *
910
 * The above copyright notice and this permission notice shall be included in
911
 * all copies or substantial portions of the Software.
912
 *
913
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
914
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
915
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
916
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
917
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
918
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
919
 * THE SOFTWARE.
920
 *
921
 * @package      CodeIgniter
922
 * @author       EllisLab Dev Team
923
 * @copyright    Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
924
 * @copyright    Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/)
925
 * @license      http://opensource.org/licenses/MIT	MIT License
926
 * @link         http://codeigniter.com
927
 * @since        Version 1.0.0
928
 * @filesource
929
 */
930
931
/**
932
 * CodeIgniter Date Helpers
933
 *
934
 * @package        CodeIgniter
935
 * @subpackage     Helpers
936
 * @category       Helpers
937
 * @author         EllisLab Dev Team
938
 * @link           http://codeigniter.com/user_guide/helpers/date_helper.html
939
 */
940
941
// ------------------------------------------------------------------------
942
943
if ( ! function_exists('now')) {
944
    /**
945
     * now
946
     *
947
     * Get "now" time
948
     *
949
     * Returns time() based on the timezone parameter or on the
950
     * "time_reference" setting
951
     *
952
     * @param  $timezone string
953
     *
954
     * @return  int
955
     * @throws \Exception
956
     */
957
    function now($timezone = null)
958
    {
959
        if (empty($timezone)) {
960
            $timezone = config()->getItem('datetime')->timezone;
0 ignored issues
show
Bug introduced by
The method getItem() does not exist on O2System\Kernel\DataStructures\Config. Did you maybe mean getIterator()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

960
            $timezone = config()->/** @scrutinizer ignore-call */ getItem('datetime')->timezone;

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
961
        }
962
963
        if ($timezone === 'local' OR $timezone === date_default_timezone_get()) {
964
            return time();
965
        }
966
967
        $datetime = new DateTime('now', new DateTimeZone($timezone));
968
        sscanf($datetime->format('j-n-Y G:i:s'), '%d-%d-%d %d:%d:%d', $day, $month, $year, $hour, $minute, $second);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $minute seems to be never defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable $year seems to be never defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable $month seems to be never defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable $hour seems to be never defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable $second seems to be never defined.
Loading history...
969
970
        return mktime($hour, $minute, $second, $month, $day, $year);
971
    }
972
}
973
974
// ------------------------------------------------------------------------
975
976
if ( ! function_exists('mdate')) {
977
    /**
978
     * mdate
979
     *
980
     * Convert MySQL Style Datecodes
981
     *
982
     * This function is identical to PHPs date() function,
983
     * except that it allows date codes to be formatted using
984
     * the MySQL style, where each code letter is preceded
985
     * with a percent sign:  %Y %m %d etc...
986
     *
987
     * The benefit of doing dates this way is that you don't
988
     * have to worry about escaping your text letters that
989
     * match the date codes.
990
     *
991
     * @param    string
992
     * @param    int
993
     *
994
     * @return    int
995
     * @throws \Exception
996
     */
997
    function mdate($date = '', $time = '')
998
    {
999
        if ($date === '') {
1000
            return '';
0 ignored issues
show
Bug Best Practice introduced by
The expression return '' returns the type string which is incompatible with the documented return type integer.
Loading history...
1001
        } elseif (empty($time)) {
1002
            $time = now();
1003
        }
1004
1005
        $date = str_replace(
1006
            '%\\',
1007
            '',
1008
            preg_replace('/([a-z]+?){1}/i', '\\\\\\1', $date)
1009
        );
1010
1011
        return date($date, $time);
0 ignored issues
show
Bug Best Practice introduced by
The expression return date($date, $time) returns the type string which is incompatible with the documented return type integer.
Loading history...
1012
    }
1013
}
1014
1015
// ------------------------------------------------------------------------
1016
1017
if ( ! function_exists('timespan')) {
1018
    /**
1019
     * timespan
1020
     *
1021
     * Returns a span of seconds in this format:
1022
     *    10 days 14 hours 36 minutes 47 seconds
1023
     *
1024
     * @param    int      $seconds a number of seconds
1025
     * @param    int|null $time    Unix timestamp
1026
     * @param    int      $units   a number of display units
1027
     *
1028
     * @return    string
1029
     */
1030
    function timespan($seconds = 1, $time = null, $units = 7)
1031
    {
1032
        language()->loadFile('date');
1033
1034
        is_numeric($seconds) OR $seconds = 1;
1035
        is_numeric($time) OR $time = time();
1036
        is_numeric($units) OR $units = 7;
1037
1038
        $seconds = ($time <= $seconds) ? 1 : $time - $seconds;
1039
1040
        $str = [];
1041
        $years = floor($seconds / 31557600);
1042
1043
        if ($years > 0) {
1044
            $str[] = $years . ' ' . language()->getLine($years > 1 ? 'DATE_YEARS' : 'DATE_YEAR');
1045
        }
1046
1047
        $seconds -= $years * 31557600;
1048
        $months = floor($seconds / 2629743);
1049
1050
        if (count($str) < $units && ($years > 0 OR $months > 0)) {
1051
            if ($months > 0) {
1052
                $str[] = $months . ' ' . language()->getLine($months > 1 ? 'DATE_MONTHS' : 'DATE_MONTH');
1053
            }
1054
1055
            $seconds -= $months * 2629743;
1056
        }
1057
1058
        $weeks = floor($seconds / 604800);
1059
1060
        if (count($str) < $units && ($years > 0 OR $months > 0 OR $weeks > 0)) {
1061
            if ($weeks > 0) {
1062
                $str[] = $weeks . ' ' . language()->getLine($weeks > 1 ? 'DATE_WEEKS' : 'DATE_WEEK');
1063
            }
1064
1065
            $seconds -= $weeks * 604800;
1066
        }
1067
1068
        $days = floor($seconds / 86400);
1069
1070
        if (count($str) < $units && ($months > 0 OR $weeks > 0 OR $days > 0)) {
1071
            if ($days > 0) {
1072
                $str[] = $days . ' ' . language()->getLine($days > 1 ? 'DATE_DAYS' : 'DATE_DAY');
1073
            }
1074
1075
            $seconds -= $days * 86400;
1076
        }
1077
1078
        $hours = floor($seconds / 3600);
1079
1080
        if (count($str) < $units && ($days > 0 OR $hours > 0)) {
1081
            if ($hours > 0) {
1082
                $str[] = $hours . ' ' . language()->getLine($hours > 1 ? 'DATE_HOURS' : 'DATE_HOUR');
1083
            }
1084
1085
            $seconds -= $hours * 3600;
1086
        }
1087
1088
        $minutes = floor($seconds / 60);
1089
1090
        if (count($str) < $units && ($days > 0 OR $hours > 0 OR $minutes > 0)) {
1091
            if ($minutes > 0) {
1092
                $str[] = $minutes . ' ' . language()->getLine($minutes > 1 ? 'DATE_MINUTES' : 'DATE_MINUTE');
1093
            }
1094
1095
            $seconds -= $minutes * 60;
1096
        }
1097
1098
        if (count($str) === 0) {
1099
            $str[] = $seconds . ' ' . language()->getLine($seconds > 1 ? 'DATE_SECONDS' : 'DATE_SECOND');
1100
        }
1101
1102
        return implode(', ', $str);
1103
    }
1104
}
1105
1106
// ------------------------------------------------------------------------
1107
1108
if ( ! function_exists('days_in_month')) {
1109
    /**
1110
     * days_in_month
1111
     *
1112
     * Number of days in a month
1113
     *
1114
     * Takes a month/year as input and returns the number of days
1115
     * for the given month/year. Takes leap years into consideration.
1116
     *
1117
     * @param    int      $month a numeric month
1118
     * @param    int|null $year  a numeric year
1119
     *
1120
     * @return    int
1121
     */
1122
    function days_in_month($month = 0, $year = null)
1123
    {
1124
        if ($month < 1 or $month > 12) {
1125
            return 0;
1126
        } elseif ( ! is_numeric($year) or strlen($year) !== 4) {
1127
            $year = date('Y');
1128
        }
1129
1130
        if (defined('CAL_GREGORIAN')) {
1131
            return cal_days_in_month(CAL_GREGORIAN, $month, $year);
0 ignored issues
show
Bug introduced by
It seems like $year can also be of type string; however, parameter $year of cal_days_in_month() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1131
            return cal_days_in_month(CAL_GREGORIAN, $month, /** @scrutinizer ignore-type */ $year);
Loading history...
1132
        }
1133
1134
        if ($year >= 1970) {
1135
            return (int)date('t', mktime(12, 0, 0, $month, 1, $year));
0 ignored issues
show
Bug introduced by
It seems like $year can also be of type string; however, parameter $year of mktime() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1135
            return (int)date('t', mktime(12, 0, 0, $month, 1, /** @scrutinizer ignore-type */ $year));
Loading history...
1136
        }
1137
1138
        if ($month == 2) {
1139
            if ($year % 400 === 0 OR ($year % 4 === 0 && $year % 100 !== 0)) {
1140
                return 29;
1141
            }
1142
        }
1143
1144
        $days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
1145
1146
        return $days_in_month[ $month - 1 ];
1147
    }
1148
}
1149
1150
// ------------------------------------------------------------------------
1151
1152
if ( ! function_exists('local_to_gmt')) {
1153
    /**
1154
     * local_to_gmt
1155
     *
1156
     * Converts a local Unix timestamp to GMT
1157
     *
1158
     * @param int $time Unix timestamp
1159
     *
1160
     * @return int
1161
     */
1162
    function local_to_gmt($time = null)
1163
    {
1164
        $time = is_numeric($time) ? $time : time();
1165
1166
        return mktime(
1167
            gmdate('G', $time),
0 ignored issues
show
Bug introduced by
gmdate('G', $time) of type string is incompatible with the type integer expected by parameter $hour of mktime(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1167
            /** @scrutinizer ignore-type */ gmdate('G', $time),
Loading history...
1168
            gmdate('i', $time),
0 ignored issues
show
Bug introduced by
gmdate('i', $time) of type string is incompatible with the type integer expected by parameter $minute of mktime(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1168
            /** @scrutinizer ignore-type */ gmdate('i', $time),
Loading history...
1169
            gmdate('s', $time),
0 ignored issues
show
Bug introduced by
gmdate('s', $time) of type string is incompatible with the type integer expected by parameter $second of mktime(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1169
            /** @scrutinizer ignore-type */ gmdate('s', $time),
Loading history...
1170
            gmdate('n', $time),
0 ignored issues
show
Bug introduced by
gmdate('n', $time) of type string is incompatible with the type integer expected by parameter $month of mktime(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1170
            /** @scrutinizer ignore-type */ gmdate('n', $time),
Loading history...
1171
            gmdate('j', $time),
0 ignored issues
show
Bug introduced by
gmdate('j', $time) of type string is incompatible with the type integer expected by parameter $day of mktime(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1171
            /** @scrutinizer ignore-type */ gmdate('j', $time),
Loading history...
1172
            gmdate('Y', $time)
0 ignored issues
show
Bug introduced by
gmdate('Y', $time) of type string is incompatible with the type integer expected by parameter $year of mktime(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1172
            /** @scrutinizer ignore-type */ gmdate('Y', $time)
Loading history...
1173
        );
1174
    }
1175
}
1176
1177
// ------------------------------------------------------------------------
1178
1179
if ( ! function_exists('gmt_to_local')) {
1180
    /**
1181
     * gmt_to_local
1182
     *
1183
     * Converts GMT time to a localized value
1184
     *
1185
     * Takes a Unix timestamp (in GMT) as input, and returns
1186
     * at the local value based on the timezone and DST setting
1187
     * submitted
1188
     *
1189
     * @param    int    $time     Unix timestamp
1190
     * @param    string $timezone timezone
1191
     * @param    bool   $dst      whether DST is active
1192
     *
1193
     * @return    int
1194
     * @throws \Exception
1195
     */
1196
    function gmt_to_local($time = null, $timezone = 'UTC', $dst = false)
1197
    {
1198
        $time = is_numeric($time) ? $time : now();
1199
1200
        if ($time === '') {
0 ignored issues
show
introduced by
The condition $time === '' is always false.
Loading history...
1201
            return now();
1202
        }
1203
1204
        $time += timezones($timezone) * 3600;
1205
1206
        return ($dst === true) ? $time + 3600 : $time;
1207
    }
1208
}
1209
1210
// ------------------------------------------------------------------------
1211
1212
if ( ! function_exists('mysql_to_unix')) {
1213
    /**
1214
     * mysql_to_unix
1215
     *
1216
     * Converts a MySQL Timestamp to Unix
1217
     *
1218
     * @param int|string $time MySQL timestamp YYYY-MM-DD HH:MM:SS
1219
     *
1220
     * @return  int    Unix timestamp
1221
     */
1222
    function mysql_to_unix($time = '')
1223
    {
1224
        // We'll remove certain characters for backward compatibility
1225
        // since the formatting changed with MySQL 4.1
1226
        // YYYY-MM-DD HH:MM:SS
1227
1228
        $time = str_replace(['-', ':', ' '], '', $time);
1229
1230
        // YYYYMMDDHHMMSS
1231
        return mktime(
1232
            substr($time, 8, 2),
0 ignored issues
show
Bug introduced by
substr($time, 8, 2) of type string is incompatible with the type integer expected by parameter $hour of mktime(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1232
            /** @scrutinizer ignore-type */ substr($time, 8, 2),
Loading history...
1233
            substr($time, 10, 2),
0 ignored issues
show
Bug introduced by
substr($time, 10, 2) of type string is incompatible with the type integer expected by parameter $minute of mktime(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1233
            /** @scrutinizer ignore-type */ substr($time, 10, 2),
Loading history...
1234
            substr($time, 12, 2),
0 ignored issues
show
Bug introduced by
substr($time, 12, 2) of type string is incompatible with the type integer expected by parameter $second of mktime(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1234
            /** @scrutinizer ignore-type */ substr($time, 12, 2),
Loading history...
1235
            substr($time, 4, 2),
0 ignored issues
show
Bug introduced by
substr($time, 4, 2) of type string is incompatible with the type integer expected by parameter $month of mktime(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1235
            /** @scrutinizer ignore-type */ substr($time, 4, 2),
Loading history...
1236
            substr($time, 6, 2),
0 ignored issues
show
Bug introduced by
substr($time, 6, 2) of type string is incompatible with the type integer expected by parameter $day of mktime(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1236
            /** @scrutinizer ignore-type */ substr($time, 6, 2),
Loading history...
1237
            substr($time, 0, 4)
0 ignored issues
show
Bug introduced by
substr($time, 0, 4) of type string is incompatible with the type integer expected by parameter $year of mktime(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1237
            /** @scrutinizer ignore-type */ substr($time, 0, 4)
Loading history...
1238
        );
1239
    }
1240
}
1241
1242
// ------------------------------------------------------------------------
1243
1244
if ( ! function_exists('unix_to_human')) {
1245
    /**
1246
     * unix_to_human
1247
     *
1248
     * Unix to "Human"
1249
     *
1250
     * Formats Unix timestamp to the following prototype: 2006-08-21 11:35 PM
1251
     *
1252
     * @param    int    $time    Unix timestamp
1253
     * @param    bool   $seconds whether to show seconds
1254
     * @param    string $format  format: us or euro
1255
     *
1256
     * @return    string
1257
     * @throws \Exception
1258
     */
1259
    function unix_to_human($time = null, $seconds = false, $format = 'us')
1260
    {
1261
        $time = is_null($time) ? now() : $time;
1262
1263
        $result = date('Y', $time) . '-' . date('m', $time) . '-' . date('d', $time) . ' ';
1264
1265
        if ($format === 'us') {
1266
            $result .= date('h', $time) . ':' . date('i', $time);
1267
        } else {
1268
            $result .= date('H', $time) . ':' . date('i', $time);
1269
        }
1270
1271
        if ($seconds) {
1272
            $result .= ':' . date('s', $time);
1273
        }
1274
1275
        if ($format === 'us') {
1276
            return $result . ' ' . date('A', $time);
1277
        }
1278
1279
        return $result;
1280
    }
1281
}
1282
1283
// ------------------------------------------------------------------------
1284
1285
if ( ! function_exists('human_to_unix')) {
1286
    /**
1287
     * human_to_unix
1288
     *
1289
     * Convert "human" date to GMT
1290
     *
1291
     * Reverses the above process
1292
     *
1293
     * @param    string $date format: us or euro
1294
     *
1295
     * @return int
1296
     */
1297
    function human_to_unix($date = '')
1298
    {
1299
        if ($date === '') {
1300
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type integer.
Loading history...
1301
        }
1302
1303
        $date = preg_replace('/\040+/', ' ', trim($date));
1304
1305
        if ( ! preg_match(
1306
            '/^(\d{2}|\d{4})\-[0-9]{1,2}\-[0-9]{1,2}\s[0-9]{1,2}:[0-9]{1,2}(?::[0-9]{1,2})?(?:\s[AP]M)?$/i',
1307
            $date
1308
        )
1309
        ) {
1310
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type integer.
Loading history...
1311
        }
1312
1313
        sscanf($date, '%d-%d-%d %s %s', $year, $month, $day, $time, $ampm);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $day seems to be never defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable $month seems to be never defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable $time seems to be never defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable $ampm seems to be never defined.
Loading history...
1314
        sscanf($time, '%d:%d:%d', $hour, $min, $sec);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $sec seems to be never defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable $min seems to be never defined.
Loading history...
1315
        isset($sec) OR $sec = 0;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $sec seems to never exist and therefore isset should always be false.
Loading history...
1316
1317
        if (isset($ampm)) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $ampm seems to never exist and therefore isset should always be false.
Loading history...
1318
            $ampm = strtolower($ampm);
1319
1320
            if ($ampm[ 0 ] === 'p' && $hour < 12) {
1321
                $hour += 12;
1322
            } elseif ($ampm[ 0 ] === 'a' && $hour === 12) {
1323
                $hour = 0;
1324
            }
1325
        }
1326
1327
        return mktime($hour, $min, $sec, $month, $day, $year);
1328
    }
1329
}
1330
1331
// ------------------------------------------------------------------------
1332
1333
if ( ! function_exists('nice_date')) {
1334
    /**
1335
     * nice_date
1336
     *
1337
     * Turns many "reasonably-date-like" strings into something
1338
     * that is actually useful. This only works for dates after unix epoch.
1339
     *
1340
     * @param    string $bad_date The terribly formatted date-like string
1341
     * @param    string $format   Date format to return (same as php date function)
1342
     *
1343
     * @return string
1344
     */
1345
    function nice_date($bad_date = '', $format = null)
1346
    {
1347
        if (empty($bad_date)) {
1348
            return 'Unknown';
1349
        } elseif (empty($format)) {
1350
            $format = 'U';
1351
        }
1352
1353
        // Date like: YYYYMM
1354
        if (preg_match('/^\d{6}$/i', $bad_date)) {
1355
            if (in_array(substr($bad_date, 0, 2), ['19', '20'])) {
1356
                $year = substr($bad_date, 0, 4);
1357
                $month = substr($bad_date, 4, 2);
1358
            } else {
1359
                $month = substr($bad_date, 0, 2);
1360
                $year = substr($bad_date, 2, 4);
1361
            }
1362
1363
            return date($format, strtotime($year . '-' . $month . '-01'));
1364
        }
1365
1366
        // Date Like: YYYYMMDD
1367
        if (preg_match('/^(\d{2})\d{2}(\d{4})$/i', $bad_date, $matches)) {
1368
            return date($format, strtotime($matches[ 1 ] . '/01/' . $matches[ 2 ]));
1369
        }
1370
1371
        // Date Like: MM-DD-YYYY __or__ M-D-YYYY (or anything in between)
1372
        if (preg_match('/^(\d{1,2})-(\d{1,2})-(\d{4})$/i', $bad_date, $matches)) {
1373
            return date($format, strtotime($matches[ 3 ] . '-' . $matches[ 1 ] . '-' . $matches[ 2 ]));
1374
        }
1375
1376
        // Any other kind of string, when converted into UNIX time,
1377
        // produces "0 seconds after epoc..." is probably bad...
1378
        // return "Invalid Date".
1379
        if (date('U', strtotime($bad_date)) === '0') {
1380
            return 'Invalid Date';
1381
        }
1382
1383
        // It's probably a valid-ish date format already
1384
        return date($format, strtotime($bad_date));
1385
    }
1386
}
1387
1388
// ------------------------------------------------------------------------
1389
1390
if ( ! function_exists('timezones')) {
1391
    /**
1392
     * timezones
1393
     *
1394
     * Returns an array of timezones. This is a helper function
1395
     * for various other ones in this library
1396
     *
1397
     * @param string $timezone timezone
1398
     *
1399
     * @return string
1400
     */
1401
    function timezones($timezone = '')
1402
    {
1403
        // Note: Don't change the order of these even though
1404
        // some items appear to be in the wrong order
1405
1406
        $zones = [
1407
            'UM12'   => -12,
1408
            'UM11'   => -11,
1409
            'UM10'   => -10,
1410
            'UM95'   => -9.5,
1411
            'UM9'    => -9,
1412
            'UM8'    => -8,
1413
            'UM7'    => -7,
1414
            'UM6'    => -6,
1415
            'UM5'    => -5,
1416
            'UM45'   => -4.5,
1417
            'UM4'    => -4,
1418
            'UM35'   => -3.5,
1419
            'UM3'    => -3,
1420
            'UM2'    => -2,
1421
            'UM1'    => -1,
1422
            'UTC'    => 0,
1423
            'UP1'    => +1,
1424
            'UP2'    => +2,
1425
            'UP3'    => +3,
1426
            'UP35'   => +3.5,
1427
            'UP4'    => +4,
1428
            'UP45'   => +4.5,
1429
            'UP5'    => +5,
1430
            'UP55'   => +5.5,
1431
            'UP575'  => +5.75,
1432
            'UP6'    => +6,
1433
            'UP65'   => +6.5,
1434
            'UP7'    => +7,
1435
            'UP8'    => +8,
1436
            'UP875'  => +8.75,
1437
            'UP9'    => +9,
1438
            'UP95'   => +9.5,
1439
            'UP10'   => +10,
1440
            'UP105'  => +10.5,
1441
            'UP11'   => +11,
1442
            'UP115'  => +11.5,
1443
            'UP12'   => +12,
1444
            'UP1275' => +12.75,
1445
            'UP13'   => +13,
1446
            'UP14'   => +14,
1447
        ];
1448
1449
        if ($timezone === '') {
1450
            return $zones;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $zones returns the type array<string,double|integer|mixed> which is incompatible with the documented return type string.
Loading history...
1451
        }
1452
1453
        return isset($zones[ $timezone ]) ? $zones[ $timezone ] : 0;
1454
    }
1455
}
1456
1457
// ------------------------------------------------------------------------
1458
1459
if ( ! function_exists('date_range_unix')) {
1460
    /**
1461
     * date_range_unix
1462
     *
1463
     * Date range
1464
     *
1465
     * Returns a list of dates within a specified period.
1466
     *
1467
     * @param    int    $unix_start unix_start    UNIX timestamp of period start date
1468
     * @param    int    $mixed      unix_end|days    UNIX timestamp of period end date
1469
     *                              or interval in days.
1470
     * @param    mixed  $is_unix    is_unix        Specifies whether the second parameter
1471
     *                              is a UNIX timestamp or a day interval
1472
     *                              - TRUE or 'unix' for a timestamp
1473
     *                              - FALSE or 'days' for an interval
1474
     * @param    string $format     date_format    Browser date format, same as in date()
1475
     *
1476
     * @return   bool|array
1477
     * @throws \Exception
1478
     */
1479
    function date_range_unix($unix_start = null, $mixed = null, $is_unix = true, $format = 'Y-m-d')
1480
    {
1481
        if (is_null($unix_start) or is_null($mixed) or empty($format)) {
1482
            return false;
1483
        }
1484
1485
        $is_unix = ! ( ! $is_unix OR $is_unix === 'days');
1486
1487
        // Validate input and try strtotime() on invalid timestamps/intervals, just in case
1488
        if (( ! ctype_digit((string)$unix_start) && ($unix_start = @strtotime($unix_start)) === false)
1489
            OR ( ! ctype_digit((string)$mixed) && ($is_unix === false OR ($mixed = @strtotime(
1490
                        $mixed
1491
                    )) === false))
1492
            OR ($is_unix === true && $mixed < $unix_start)
1493
        ) {
1494
            return false;
1495
        }
1496
1497
        if ($is_unix && ($unix_start == $mixed OR date($format, $unix_start) === date($format, $mixed))) {
1498
            return [date($format, $unix_start)];
1499
        }
1500
1501
        $range = [];
1502
1503
        /* NOTE: Even though the DateTime object has many useful features, it appears that
1504
         *	 it doesn't always handle properly timezones, when timestamps are passed
1505
         *	 directly to its constructor. Neither of the following gave proper results:
1506
         *
1507
         *		new DateTime('<timestamp>')
1508
         *		new DateTime('<timestamp>', '<timezone>')
1509
         *
1510
         *	 --- available in PHP 5.3:
1511
         *
1512
         *		DateTime::createFromFormat('<format>', '<timestamp>')
1513
         *		DateTime::createFromFormat('<format>', '<timestamp>', '<timezone')
1514
         *
1515
         *	 ... so we'll have to set the timestamp after the object is instantiated.
1516
         *	 Furthermore, in PHP 5.3 we can use DateTime::setTimestamp() to do that and
1517
         *	 given that we have UNIX timestamps - we should use it.
1518
        */
1519
        $from = new DateTime();
1520
1521
        if (is_php('5.3')) {
1522
            $from->setTimestamp($unix_start);
1523
            if ($is_unix) {
1524
                $arg = new DateTime();
1525
                $arg->setTimestamp($mixed);
1526
            } else {
1527
                $arg = (int)$mixed;
1528
            }
1529
1530
            $period = new DatePeriod($from, new DateInterval('P1D'), $arg);
0 ignored issues
show
Bug introduced by
It seems like $arg can also be of type integer; however, parameter $end of DatePeriod::__construct() does only seem to accept DateTimeInterface, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1530
            $period = new DatePeriod($from, new DateInterval('P1D'), /** @scrutinizer ignore-type */ $arg);
Loading history...
1531
            foreach ($period as $date) {
1532
                $range[] = $date->format($format);
1533
            }
1534
1535
            /* If a period end date was passed to the DatePeriod constructor, it might not
1536
             * be in our results. Not sure if this is a bug or it's just possible because
1537
             * the end date might actually be less than 24 hours away from the previously
1538
             * generated DateTime object, but either way - we have to append it manually.
1539
             */
1540
            if ( ! is_int($arg) && $range[ count($range) - 1 ] !== $arg->format($format)) {
1541
                $range[] = $arg->format($format);
1542
            }
1543
1544
            return $range;
1545
        }
1546
1547
        $from->setDate(date('Y', $unix_start), date('n', $unix_start), date('j', $unix_start));
0 ignored issues
show
Bug introduced by
date('Y', $unix_start) of type string is incompatible with the type integer expected by parameter $year of DateTime::setDate(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1547
        $from->setDate(/** @scrutinizer ignore-type */ date('Y', $unix_start), date('n', $unix_start), date('j', $unix_start));
Loading history...
Bug introduced by
date('n', $unix_start) of type string is incompatible with the type integer expected by parameter $month of DateTime::setDate(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1547
        $from->setDate(date('Y', $unix_start), /** @scrutinizer ignore-type */ date('n', $unix_start), date('j', $unix_start));
Loading history...
Bug introduced by
date('j', $unix_start) of type string is incompatible with the type integer expected by parameter $day of DateTime::setDate(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1547
        $from->setDate(date('Y', $unix_start), date('n', $unix_start), /** @scrutinizer ignore-type */ date('j', $unix_start));
Loading history...
1548
        $from->setTime(date('G', $unix_start), date('i', $unix_start), date('s', $unix_start));
0 ignored issues
show
Bug introduced by
date('s', $unix_start) of type string is incompatible with the type integer expected by parameter $second of DateTime::setTime(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1548
        $from->setTime(date('G', $unix_start), date('i', $unix_start), /** @scrutinizer ignore-type */ date('s', $unix_start));
Loading history...
Bug introduced by
date('i', $unix_start) of type string is incompatible with the type integer expected by parameter $minute of DateTime::setTime(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1548
        $from->setTime(date('G', $unix_start), /** @scrutinizer ignore-type */ date('i', $unix_start), date('s', $unix_start));
Loading history...
Bug introduced by
date('G', $unix_start) of type string is incompatible with the type integer expected by parameter $hour of DateTime::setTime(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1548
        $from->setTime(/** @scrutinizer ignore-type */ date('G', $unix_start), date('i', $unix_start), date('s', $unix_start));
Loading history...
1549
        if ($is_unix) {
1550
            $arg = new DateTime();
1551
            $arg->setDate(date('Y', $mixed), date('n', $mixed), date('j', $mixed));
1552
            $arg->setTime(date('G', $mixed), date('i', $mixed), date('s', $mixed));
1553
        } else {
1554
            $arg = (int)$mixed;
1555
        }
1556
        $range[] = $from->format($format);
1557
1558
        if (is_int($arg)) // Day intervals
1559
        {
1560
            do {
1561
                $from->modify('+1 day');
1562
                $range[] = $from->format($format);
1563
            } while (--$arg > 0);
1564
        } else // end date UNIX timestamp
1565
        {
1566
            for ($from->modify('+1 day'), $end_check = $arg->format('Ymd'); $from->format(
1567
                'Ymd'
1568
            ) < $end_check; $from->modify('+1 day')
1569
            ) {
1570
                $range[] = $from->format($format);
1571
            }
1572
1573
            // Our loop only appended dates prior to our end date
1574
            $range[] = $arg->format($format);
1575
        }
1576
1577
        return $range;
1578
    }
1579
}