PluginProbe
ShiftController Employee Shift Scheduling / 4.9.26
ShiftController Employee Shift Scheduling v4.9.26
4.9.97 4.9.96 4.9.95 4.9.74 4.9.75 4.9.76 4.9.77 4.9.78 4.9.84 4.9.85 4.9.87 4.9.91 4.9.92 trunk 2.1.0 2.1.1 2.1.2 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 3.2.4 All 38 releases
shiftcontroller / hc3 / time.php

time.php in ShiftController Employee Shift Scheduling 4.9.26, at hc3/time.php

837 lines 18.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php if (! defined('ABSPATH')) exit; // Exit if accessed directly
2 interface HC3_ITime
3 {
4 public function setTimezone( $tz );
5 public function setNow();
6 public function formatToDatepicker();
7 public function formatDate( $format = '' );
8 public function formatDateWithWeekday( $format = '' );
9 public function formatDateDb();
10 public function setDateDb( $date );
11 public function setDateTimeDb( $datetime );
12 public function formatTime();
13 public function formatDateTimeDb();
14 public function formatTimeDb();
15 public function setStartDay();
16 public function getWeekStartsOn();
17 public function setStartWeek();
18 public function setStartMonth();
19 public function setEndMonth();
20 public function setStartYear();
21 public function setEndYear();
22 public function setEndWeek();
23 public function getYear();
24 public function getDay();
25 public function getWeekday();
26 public function getMonthName();
27 public function getWeekdayName();
28 public function formatDateRange( $date1, $date2, $with_weekday = FALSE );
29 public function getMonthMatrix( $skipWeekdays = array() );
30 public function getParts();
31 public function getWeekdays();
32 public function sortWeekdays( $wds );
33 public function formatDuration( $seconds );
34 public function getTimeInDay();
35 }
36
37 class HC3_Time extends DateTime implements HC3_ITime
38 {
39 public $timeFormat = 'g:ia';
40 public $dateFormat = 'j M Y';
41 public $weekStartsOn = 0;
42
43 protected $_months = array();
44 protected $_weekdays = array();
45
46 var $timezone = '';
47
48 function __construct( HC3_Settings $settings = NULL )
49 {
50 parent::__construct();
51
52 $localiseThis = array('__Jan__', '__Feb__', '__Mar__', '__Apr__', '__May__', '__Jun__', '__Jul__', '__Aug__', '__Sep__', '__Oct__', '__Nov__', '__Dec__');
53
54 $this->_months = array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
55 $this->_weekdays = array('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat');
56
57 if( $settings ){
58 if( $time_format = $settings->get('datetime_time_format') ){
59 $this->timeFormat = $time_format;
60 }
61 if( $date_format = $settings->get('datetime_date_format') ){
62 $this->dateFormat = $date_format;
63 }
64 if( $week_starts = $settings->get('datetime_week_starts') ){
65 $this->weekStartsOn = $week_starts;
66 }
67
68 $tz = '';
69
70 $tz = $settings->get('datetime_timezone');
71 $tz = trim( $tz );
72
73 if( ! strlen($tz) ){
74 $tz = $this->getDefaultTimezone();
75 $tz = trim( $tz );
76 }
77
78 if( strlen($tz) ){
79 $this->setTimezone( $tz );
80 }
81 }
82
83 // if( defined('WPINC') ){
84 // $tz = get_option('timezone_string');
85 // if( ! strlen($tz) ){
86 // $offset = get_option('gmt_offset');
87 // if( $offset ){
88 // $tz = 'Etc/GMT';
89 // if( $offset > 0 ){
90 // $tz .= '+' . $offset;
91 // }
92 // else {
93 // $tz .= '-' . -$offset;
94 // }
95 // }
96 // }
97
98 // $this->setTimezone( $tz );
99 // }
100 }
101
102 public function setTimezone( $tz )
103 {
104 if( is_array($tz) )
105 $tz = $tz[0];
106
107 if( ! $tz )
108 $tz = date_default_timezone_get();
109
110 // check timezone
111 $timezones = $this->getTimezones();
112
113 if( isset($timezones[$tz]) OR ('UTC' == $tz) ){
114 $this->timezone = $tz;
115 $tz = new DateTimeZone( $tz );
116 parent::setTimezone( $tz );
117 }
118 }
119
120 public function setNow()
121 {
122 $this->setTimestamp( time() );
123 return $this;
124 }
125
126 public function formatToDatepicker()
127 {
128 $dateFormat = $this->dateFormat;
129
130 $pattern = array(
131 //day
132 'd', //day of the month
133 'j', //3 letter name of the day
134 'l', //full name of the day
135 'z', //day of the year
136
137 //month
138 'F', //Month name full
139 'M', //Month name short
140 'n', //numeric month no leading zeros
141 'm', //numeric month leading zeros
142
143 //year
144 'Y', //full numeric year
145 'y' //numeric year: 2 digit
146 );
147
148 $replace = array(
149 'dd','d','DD','o',
150 'MM','M','m','mm',
151 'yyyy','y'
152 );
153 foreach($pattern as &$p){
154 $p = '/'.$p.'/';
155 }
156 return preg_replace( $pattern, $replace, $dateFormat );
157 }
158
159 public function formatDateWithWeekday( $format = '' )
160 {
161 $out = array();
162 $out[] = $this->getWeekdayName();
163 $out[] = $this->formatDate( $format );
164 $out = join(', ', $out);
165 return $out;
166 }
167
168 public function formatDate( $format = '' )
169 {
170 if( ! strlen($format) ){
171 $format = $this->dateFormat;
172 }
173
174 $return = $this->format( $format );
175
176 // replace English months to localized ones
177 $replace_from = array();
178 $replace_to = array();
179 foreach( $this->_months as $month ){
180 $replace_from[] = $month;
181 $replace_to[] = '__' . $month . '__';
182 }
183
184 $return = str_replace( $replace_from, $replace_to, $return );
185 return $return;
186 }
187
188 public function formatDateDb()
189 {
190 $dateFormat = 'Ymd';
191 $return = $this->format( $dateFormat );
192 return $return;
193 }
194
195 public function setDateDb( $date )
196 {
197 list( $year, $month, $day ) = $this->_splitDate( $date );
198 $year = (int) $year;
199 $month = (int) $month;
200 $day = (int) $day;
201
202 $this->setDate( $year, $month, $day );
203 $this->setTime( 0, 0, 0 );
204 return $this;
205 }
206
207 public function setDateTimeDb( $datetime )
208 {
209 $date = substr($datetime, 0, 8);
210 $this->setDateDb( $date );
211
212 $hours = substr($datetime, 8, 2);
213 $minutes = substr($datetime, 10, 2);
214 $this->setTime( $hours, $minutes, 0 );
215
216 return $this;
217 }
218
219 public function formatTime( $format = NULL )
220 {
221 if( NULL === $format ) $format = $this->timeFormat;
222
223 if( '12short' === $format ){
224 $ret = $this->format( 'g:ia' );
225 $ret = str_replace( ':00', '', $ret );
226 }
227 elseif( '12xshort' === $format ){
228 $ret = $this->format( 'g:ia' );
229 $ret = str_replace( 'am', 'a', $ret );
230 $ret = str_replace( 'pm', 'p', $ret );
231 $ret = str_replace( ':00', '', $ret );
232 }
233 elseif( '24short' === $format ){
234 $ret = $this->format( 'H:i' );
235 $ret = preg_replace( '/0(\d\:)/', '${1}', $ret );
236 $ret = str_replace( ':00', '', $ret );
237 }
238 else {
239 $ret = $this->format( $format );
240 }
241
242 return $ret;
243 }
244
245 protected function _splitDate( $string )
246 {
247 $year = substr( $string, 0, 4 );
248 $month = substr( $string, 4, 2 );
249 $day = substr( $string, 6, 4 );
250 $return = array( $year, $month, $day );
251 return $return;
252 }
253
254 public function formatDateTimeDb()
255 {
256 $date = $this->formatDateDb();
257 $time = $this->formatTimeDb();
258 $return = $date . $time;
259 return $return;
260 }
261
262 public function formatTimeDb()
263 {
264 $h = $this->format('G');
265 $m = $this->format('i');
266
267 $h = str_pad( $h, 2, 0, STR_PAD_LEFT );
268 $m = str_pad( $m, 2, 0, STR_PAD_LEFT );
269
270 $return = $h . $m;
271 return $return;
272 }
273
274 public function setStartDay()
275 {
276 $this->setTime( 0, 0, 0 );
277 return $this;
278 }
279
280 public function setEndDay()
281 {
282 $this->setTime( 23, 59, 0 );
283 return $this;
284 }
285
286 public function getTimeInDay()
287 {
288 $timestamp = $this->getTimestamp();
289
290 $this->setStartDay();
291 $timestamp2 = $this->getTimestamp();
292
293 $return = $timestamp - $timestamp2;
294
295 $this->setTimestamp( $timestamp );
296 return $return;
297 }
298
299 public function getWeekStartsOn()
300 {
301 return $this->weekStartsOn;
302 }
303
304 public function setStartWeek()
305 {
306 $this->setStartDay();
307 $weekDay = $this->getWeekday();
308
309 while( $weekDay != $this->weekStartsOn ){
310 $this->modify( '-1 day' );
311 $weekDay = $this->getWeekday();
312 }
313
314 return $this;
315 }
316
317 public function setStartMonth()
318 {
319 $year = $this->format('Y');
320 $month = $this->format('m');
321 $day = '01';
322
323 $date = $year . $month . $day;
324 $this->setDateDb( $date );
325 $this->setTime( 0, 0, 0 );
326
327 return $this;
328 }
329
330 public function setEndMonth()
331 {
332 $this->modify('+1 month');
333
334 $year = $this->format('Y');
335 $month = $this->format('m');
336 $day = '01';
337
338 $date = $year . $month . $day;
339 $this->setDateDb( $date );
340 $this->modify('-1 day')
341 ->setEndDay()
342 ;
343
344 return $this;
345 }
346
347 public function setStartYear()
348 {
349 $year = $this->format('Y');
350 $month = '01';
351 $day = '01';
352
353 $date = $year . $month . $day;
354 $this->setDateDb( $date );
355 $this->setTime( 0, 0, 0 );
356
357 return $this;
358 }
359
360 public function setEndYear()
361 {
362 $this->modify('+1 year');
363
364 $year = $this->format('Y');
365 $month = '01';
366 $day = '01';
367
368 $date = $year . $month . $day;
369 $this->setDateDb( $date );
370 $this->modify('-1 day')
371 ->setEndDay()
372 ;
373
374 return $this;
375 }
376
377 public function setEndWeek()
378 {
379 $this->setStartDay();
380 $this->modify( '+1 day' );
381 $weekDay = $this->getWeekday();
382
383 while( $weekDay != $this->weekStartsOn ){
384 $this->modify( '+1 day' );
385 $weekDay = $this->getWeekday();
386 }
387
388 $this->modify( '-1 day' )
389 ->setEndDay()
390 ;
391
392 return $this;
393 }
394
395 public function getYear()
396 {
397 $return = $this->format('Y');
398 return $return;
399 }
400
401 public function getDay()
402 {
403 $return = $this->format('j');
404 return $return;
405 }
406
407 public function getWeekday()
408 {
409 $return = $this->format('w');
410 return $return;
411 }
412
413 public function getWeekNo()
414 {
415 $return = $this->format('W'); // but it works out of the box for week starts on monday
416 $weekday = $this->getWeekday();
417 if( ! $weekday ){ // sunday
418 if( ! $this->weekStartsOn ){
419 $return = $return + 1;
420 }
421 }
422 return $return;
423 }
424
425 public function getMonthName()
426 {
427 $month = $this->format('n') - 1;
428 $return = $this->_months[$month];
429 $return = '__' . $return . '__';
430 return $return;
431 }
432
433 public function getWeekdayName()
434 {
435 $wd = $this->getWeekday();
436 $return = $this->_weekdays[$wd];
437 $return = '__' . $return . '__';
438 return $return;
439 }
440
441 public function formatDateRange( $date1, $date2, $with_weekday = FALSE )
442 {
443 list( $start_date_view, $end_date_view ) = $this->_formatDateRange( $date1, $date2, $with_weekday );
444
445 if( $end_date_view ){
446 $return = $start_date_view . ' - ' . $end_date_view;
447 }
448 else {
449 $return = $start_date_view;
450 }
451 return $return;
452 }
453
454 protected function _formatDateRange( $date1, $date2, $with_weekday = FALSE )
455 {
456 $return = array();
457 $skip = array();
458
459 if( $date1 == $date2 ){
460 $this->setDateDb( $date1 );
461 $view_date1 = $this->formatDate();
462 if( $with_weekday ){
463 $view_date1 = $this->formatWeekdayShort() . ', ' . $view_date1;
464 }
465 $return[] = $view_date1;
466 $return[] = NULL;
467 return $return;
468 }
469
470 $this->setDateDb( $date1 );
471 $year1 = $this->getYear();
472 $month1 = $this->format('n');
473
474 $this->setDateDb( $date2 );
475 $year2 = $this->getYear();
476 $month2 = $this->format('n');
477
478 if( $year2 == $year1 )
479 $skip['year'] = TRUE;
480 if( ($year2 == $year1) && ($month2 == $month1) )
481 $skip['month'] = TRUE;
482
483 if( $skip ){
484 $date_format = $this->dateFormat;
485 $date_format_short = $date_format;
486
487 $tags = array('m', 'n', 'M');
488 foreach( $tags as $t ){
489 $pos_m_original = strpos($date_format_short, $t);
490 if( $pos_m_original !== FALSE )
491 break;
492 }
493
494 if( isset($skip['year']) ){
495 $pos_y = strpos($date_format_short, 'Y');
496 if( $pos_y == 0 ){
497 $date_format_short = substr_replace( $date_format_short, '', $pos_y, 2 );
498 }
499 else {
500 $date_format_short = substr_replace( $date_format_short, '', $pos_y - 1, 2 );
501 }
502 }
503
504 if( isset($skip['month']) ){
505 $tags = array('m', 'n', 'M');
506 foreach( $tags as $t ){
507 $pos_m = strpos($date_format_short, $t);
508 if( $pos_m !== FALSE )
509 break;
510 }
511
512 // month going first, do not replace
513 if( $pos_m_original == 0 ){
514 // $date_format_short = substr_replace( $date_format_short, '', $pos_m, 2 );
515 }
516 else {
517 // month going first, do not replace
518 if( $pos_m == 0 ){
519 $date_format_short = substr_replace( $date_format_short, '', $pos_m, 2 );
520 }
521 else {
522 $date_format_short = substr_replace( $date_format_short, '', $pos_m - 1, 2 );
523 }
524 }
525 }
526
527 if( $pos_y == 0 ){ // skip year in the second part
528 $date_format1 = $date_format;
529 $date_format2 = $date_format_short;
530 }
531 else {
532 $date_format1 = $date_format_short;
533 $date_format2 = $date_format;
534 }
535
536 $this->setDateDb( $date1 );
537
538 $view_date1 = $this->formatDate( $date_format1 );
539 if( $with_weekday ){
540 $view_date1 = $this->formatWeekdayShort() . ', ' . $view_date1;
541 }
542 $return[] = $view_date1;
543
544 $this->setDateDb( $date2 );
545 $view_date2 = $this->formatDate( $date_format2 );
546 if( $with_weekday ){
547 $view_date2 = $this->formatWeekdayShort() . ', ' . $view_date2;
548 }
549 $return[] = $view_date2;
550 }
551 else {
552 $this->setDateDb( $date1 );
553 $view_date1 = $this->formatDate();
554 if( $with_weekday ){
555 $view_date1 = $this->formatWeekdayShort() . ', ' . $view_date1;
556 }
557 $return[] = $view_date1;
558
559 $this->setDateDb( $date2 );
560 $view_date2 = $this->formatDate();
561 if( $with_weekday ){
562 $view_date2 = $this->formatWeekdayShort() . ', ' . $view_date2;
563 }
564 $return[] = $view_date2;
565 }
566
567 return $return;
568 }
569
570 public function getMonthMatrix( $skipWeekdays = array() )
571 {
572 $overlap = TRUE; // if to show dates of prev/next month
573 $overlap = FALSE; // if to show dates of prev/next month
574
575 $matrix = array();
576 $currentMonthDay = 0;
577
578 $this->setStartMonth();
579 if( $overlap ){
580 $this->setStartWeek();
581 }
582 $startDate = $this->formatDateDb();
583
584 // echo "END DATE = $endDate<br>";
585
586 $this->setEndMonth();
587 if( $overlap ){
588 // $this->setEndWeek();
589 }
590 $endDate = $this->formatDateDb();
591 // echo "START/END DATE = $startDate/$endDate<br>";
592
593 $rexDate = $startDate;
594 if( $overlap ){
595 $this->setDateDb( $startDate );
596 $this->setStartWeek();
597 $rexDate = $this->formatDateDb();
598 }
599
600 $this->setDateDb( $startDate );
601 $this->setStartWeek();
602 $rexDate = $this->formatDateDb();
603
604 // echo "START DATE = $startDate, END DATE = $endDate, REX DATE = $rexDate<br>";
605
606 $this->setDateDb( $rexDate );
607 while( $rexDate <= $endDate ){
608 $week = array();
609 $weekSet = FALSE;
610 for( $weekDay = 0; $weekDay <= 6; $weekDay++ ){
611 $thisWeekday = $this->getWeekday();
612 $setDate = $rexDate;
613
614 if( ! $overlap ){
615 if(
616 ( $rexDate > $endDate ) OR
617 ( $rexDate < $startDate )
618 ){
619 $setDate = NULL;
620 }
621 }
622
623 // $week[ $thisWeekday ] = $setDate;
624
625 if( (! $skipWeekdays) OR (! in_array($thisWeekday, $skipWeekdays)) ){
626 $week[] = $setDate;
627 if( NULL !== $setDate ){
628 $weekSet = TRUE;
629 }
630 }
631
632 $this->modify('+1 day');
633 $rexDate = $this->formatDateDb();
634
635 // if( $exact && ($rexDate >= $endDate) ){
636 // break;
637 // }
638 }
639
640 if( $weekSet )
641 $matrix[] = $week;
642 }
643 return $matrix;
644 }
645
646 public function getWeeksMatrix( $weeks = 4, $skipWeekdays = array() )
647 {
648 $matrix = array();
649 $currentMonthDay = 0;
650
651 $this->setStartWeek();
652 $startDate = $this->formatDateDb();
653
654 // echo "END DATE = $endDate<br>";
655 $this->modify( '+' . $weeks . ' weeks' )->modify('-1 day');
656 $endDate = $this->formatDateDb();
657 // echo "START/END DATE = $startDate/$endDate<br>";
658
659 $rexDate = $startDate;
660
661 // echo "START DATE = $startDate, END DATE = $endDate, REX DATE = $rexDate<br>";
662
663 $this->setDateDb( $rexDate );
664 while( $rexDate <= $endDate ){
665 $week = array();
666 $weekSet = FALSE;
667 for( $weekDay = 0; $weekDay <= 6; $weekDay++ ){
668 $thisWeekday = $this->getWeekday();
669 $setDate = $rexDate;
670
671 // $week[ $thisWeekday ] = $setDate;
672
673 if( (! $skipWeekdays) OR (! in_array($thisWeekday, $skipWeekdays)) ){
674 $week[] = $setDate;
675 if( NULL !== $setDate ){
676 $weekSet = TRUE;
677 }
678 }
679
680 $this->modify('+1 day');
681 $rexDate = $this->formatDateDb();
682
683 // if( $exact && ($rexDate >= $endDate) ){
684 // break;
685 // }
686 }
687
688 if( $weekSet )
689 $matrix[] = $week;
690 }
691 return $matrix;
692 }
693
694 public function getParts()
695 {
696 $full = $this->formatDateTimeDb();
697
698 $year = substr( $full, 0, 4 );
699 $month = substr( $full, 4, 2 );
700 $day = substr( $full, 6, 2 );
701 $hour = substr( $full, 8, 2 );
702 $min = substr( $full, 10, 2 );
703
704 $return = array( $year, $month, $day, $hour, $min );
705 return $return;
706 }
707
708 public function getWeekdays()
709 {
710 $return = array();
711
712 $wkds = array( 0, 1, 2, 3, 4, 5, 6 );
713 $wkds = $this->sortWeekdays( $wkds );
714
715 reset( $wkds );
716 foreach( $wkds as $wkd ){
717 $return[ $wkd ] = '__' . $this->_weekdays[$wkd] . '__';
718 }
719 return $return;
720 }
721
722 public function sortWeekdays( $wds )
723 {
724 $return = array();
725 $later = array();
726
727 sort( $wds );
728 reset( $wds );
729 foreach( $wds as $wd ){
730 if( $wd < $this->weekStartsOn )
731 $later[] = $wd;
732 else
733 $return[] = $wd;
734 }
735 $return = array_merge( $return, $later );
736 return $return;
737 }
738
739 public function formatDuration( $seconds )
740 {
741 $hours = floor( $seconds / (60 * 60) );
742 $remain = $seconds - $hours * (60 * 60);
743 $minutes = floor( $remain / 60 );
744
745 $hoursView = $hours;
746 $minutesView = sprintf( '%02d', $minutes );
747
748 $return = $hoursView . ':' . $minutesView;
749 // $return = gmdate( "H:i", $this->getDuration() );
750 return $return;
751 }
752
753 public function getTimezones()
754 {
755 $skipStarts = array('Brazil/', 'Canada/', 'Chile/', 'Etc/', 'Mexico/', 'US/');
756 $skipStarts = array( 'Etc/' );
757 // $skipStarts = array();
758 $return = array();
759
760 if( defined('DateTimeZone::ALL_WITH_BC') )
761 $timezones = timezone_identifiers_list( DateTimeZone::ALL_WITH_BC );
762 else
763 $timezones = timezone_identifiers_list();
764
765 reset( $timezones );
766 foreach( $timezones as $tz ){
767 if( false === strpos($tz, "/") )
768 continue;
769
770 $skipIt = false;
771 reset( $skipStarts );
772 foreach( $skipStarts as $skip ){
773 if( substr($tz, 0, strlen($skip)) == $skip ){
774 $skipIt = true;
775 break;
776 }
777 }
778 if( $skipIt )
779 continue;
780
781 $tzTitle = $this->timezoneTitle( $tz );
782 $return[ $tz ] = $tzTitle;
783 }
784
785 return $return;
786 }
787
788 public function timezoneTitle( $tz, $showOffset = FALSE )
789 {
790 if( is_array($tz) )
791 $tz = $tz[0];
792
793 $tzobj = new DateTimeZone( $tz );
794 $dtobj = new DateTime();
795 $dtobj->setTimezone( $tzobj );
796
797 if( $showOffset ){
798 $offset = $tzobj->getOffset( $dtobj );
799 $offsetString = 'GMT';
800 $offsetString .= ($offset >= 0) ? '+' : '';
801 $offsetString = $offsetString . ( $offset/(60 * 60) );
802 $return = $tz . ' (' . $offsetString . ')';
803 }
804 else {
805 $return = $tz;
806 }
807
808 return $return;
809 }
810
811 public function getDefaultTimezone()
812 {
813 $return = date_default_timezone_get();
814
815 if( defined('WPINC') ){
816 $tz = get_option('timezone_string');
817 if( ! strlen($tz) ){
818 $offset = get_option('gmt_offset');
819 if( $offset ){
820 $tz = 'Etc/GMT';
821 if( $offset > 0 ){
822 $tz .= '+' . $offset;
823 }
824 else {
825 $tz .= '-' . -$offset;
826 }
827 }
828 }
829
830 if( strlen($tz) ){
831 $return = $tz;
832 }
833 }
834
835 return $return;
836 }
837 }