Guest User

Untitled

a guest
Dec 11th, 2018
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.66 KB | None | 0 0
  1. <?php
  2. class BusinessCalendar
  3. {
  4.  
  5. private $debugMessage;
  6. private $debug = false;
  7.  
  8. public function __construct($debug = false)
  9. {
  10. $this->debug = $debug;
  11. }
  12.  
  13. public function setDebug($debug = true)
  14. {
  15. $this->debug = $debug;
  16. }
  17.  
  18. public function getNextBusinessDays($date, $workingDays, $holidays, $numDays)
  19. {
  20. $days = $this->getBusinessDays($date, $workingDays, $holidays, true, $numDays);
  21.  
  22. $this->debugMessage = sprintf(
  23. 'The next %d business after %s are %s',
  24. $numDays,
  25. $this->formatDate($date),
  26. implode(', ', $this->formatDate($days, true))
  27. );
  28. $this->printDebugMessage();
  29.  
  30. return $days;
  31. }
  32.  
  33. public function getPriorBusinessDays($date, $workingDays, $holidays, $numDays)
  34. {
  35. return $this->getBusinessDays($date, $workingDays, $holidays, false, $numDays);
  36. }
  37.  
  38. public function getBusinessDaysForAPeriod($startDate, $endDate, $workingDays, $holidays)
  39. {
  40. $days = [];
  41. $day = $startDate;
  42. while ($day < $endDate) {
  43. $day = $this->getTradingDate($day, $workingDays, $holidays, true);
  44. $days[] = $day;
  45. }
  46.  
  47. $this->debugMessage = sprintf(
  48. 'There are %d business day(s) between %s and %s which are %s',
  49. count($days),
  50. $this->formatDate($startDate),
  51. $this->formatDate($endDate),
  52. implode(', ', $this->formatDate($days, true))
  53. );
  54. $this->printDebugMessage();
  55. return $days;
  56. }
  57.  
  58. private function printDebugMessage()
  59. {
  60. if (!$this->debug) {
  61. return;
  62. }
  63. echo $this->debugMessage.PHP_EOL.PHP_EOL;
  64. }
  65.  
  66. public function getNextBusinessDay($date, $workingDays, $holidays)
  67. {
  68. $day = $this->getTradingDate($date, $workingDays, $holidays, true);
  69. // \033[1;32m
  70. $this->debugMessage = sprintf(
  71. "The next business day after %s is %s",
  72. $this->formatDate($date),
  73. $this->formatDate($day, true)
  74. );
  75. $this->printDebugMessage();
  76.  
  77. return $day;
  78. }
  79.  
  80. public function getPriorBusinessDay($date, $workingDays, $holidays)
  81. {
  82. $day = $this->getTradingDate($date, $workingDays, $holidays, false);
  83.  
  84. $this->debugMessage = sprintf(
  85. 'The business day before %s was %s',
  86. $this->formatDate($date),
  87. $this->formatDate($day, true)
  88. );
  89. $this->printDebugMessage();
  90. return $day;
  91. }
  92.  
  93. private function formatDate($dates, $highlight = false)
  94. {
  95. $ret = [];
  96. if (is_array($dates)) {
  97. array_walk(
  98. $dates,
  99. function ($date) use (&$ret, $highlight) {
  100. $ret[] = $this->formatDate($date, $highlight);
  101. }
  102. );
  103. } else {
  104. // return sprintf("\033[40;1m%s\033[0m", (new \DateTime($dates))->format('D d M y'));
  105. $format = $highlight ? "\033[30;47m%s\033[0m" : "%s";
  106. return sprintf($format, (new \DateTime($dates))->format('D, j M y'));
  107. }
  108. return $ret;
  109. }
  110.  
  111. private function getBusinessDays($date, $workingDays, $holidays, $next, $numDays)
  112. {
  113. $days = [];
  114. $day = $date;
  115. for ($i = 0; $i < $numDays; $i++) {
  116. $day = $this->getTradingDate($day, $workingDays, $holidays, $next);
  117. $days[] = $day;
  118. }
  119. return $days;
  120. }
  121.  
  122. private function getTradingDate($date, $weekdays, $holidays, $next = true)
  123. {
  124. $date = new \DateTime($date);
  125.  
  126. $IsAWeekday = function (\DateTime $date) use ($weekdays) {
  127. return in_array($date->format('N'), $weekdays);
  128. };
  129.  
  130. $IsAHoliday = function (\DateTime $date) use ($holidays) {
  131. return $holidays ?
  132. in_array($date->format('Y-m-d'), $holidays) : false;
  133. };
  134.  
  135. do {
  136. if ($next) {
  137. $date->add(new \DateInterval('P1D'));
  138. } else {
  139. $date->sub(new \DateInterval('P1D'));
  140. }
  141. } while (!($IsAWeekday($date) && ! $IsAHoliday($date)));
  142.  
  143. return $date->format('Y-m-d');
  144. }
  145. }
  146.  
  147. $calendar = new BusinessCalendar(true);
  148. $weekdays = [1,2,3,4,5];
  149.  
  150. $day = '2018-12-11';
  151. $nextDay = $calendar->getNextBusinessDay($day, $weekdays, []);
  152. $nextDay = $calendar->getPriorBusinessDay($day, $weekdays, []);
  153.  
  154. $nextDay = $calendar->getNextBusinessDay($day, $weekdays, ['2018-08-06', '2018-08-07']);
  155. $nextDays = $calendar->getNextBusinessDays($day, $weekdays, ['2018-08-06', '2018-08-07'], 2);
  156. $nextDays = $calendar->getBusinessDaysForAPeriod(
  157. $day,
  158. '2018-12-18',
  159. $weekdays,
  160. ['2018-12-12', '2018-12-15']
  161. );
Add Comment
Please, Sign In to add comment