Last active
August 29, 2015 14:01
-
-
Save ahmadshah/b61f303b1c17ff52a45d to your computer and use it in GitHub Desktop.
Date Recurring Scheduler By Month
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function batch_scheduler($start, $end, $interval) { | |
$years = array(); | |
$recurrings = array($start); | |
preg_match('/^[0-9]{4}/', $start, $startYear); | |
preg_match('/^[0-9]{4}/', $end, $endYear); | |
$diff = $endYear[0] - $startYear[0]; | |
if ($diff > 5) { | |
for ($i = 0; $i <= $diff; $i = $i+5) { | |
$years[] = $startYear[0] + $i; | |
} | |
if ( ! in_array($endYear[0], $years)) { | |
$years[] = $endYear[0]; | |
} | |
for ($m = 1; $m < count($years); $m++) { | |
$s = preg_replace('/^[0-9]{4}/', $years[$m-1], $start); | |
$e = preg_replace('/^[0-9]{4}/', $years[$m], $end); | |
$scheduler = new Scheduler($s, $e); | |
$recurrings[] = $scheduler->setRecurring($interval)->get(); | |
} | |
} else { | |
$scheduler = new Scheduler($start, $end); | |
$recurrings[] = $scheduler->setRecurring($interval)->get(); | |
} | |
return array_flatten(array_unique(array_flatten($recurrings))); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use \Exception; | |
use Carbon\Carbon; | |
class Scheduler { | |
/** | |
* Scheduler starting date | |
* | |
* @var string | |
*/ | |
protected $startDate; | |
/** | |
* Scheduler end date | |
* | |
* @var string | |
*/ | |
protected $endDate; | |
/** | |
* Recurrings scheduler dates | |
* | |
* @var array | |
*/ | |
protected $recurrings = array(); | |
/** | |
* Instantiate scheduler | |
* | |
* @param string $startDate | |
* @param string $endDate | |
*/ | |
public function __construct($startDate, $endDate) | |
{ | |
$this->setDates($startDate, $endDate); | |
} | |
/** | |
* Set start and end date for scheduler | |
* | |
* @param string $startDate | |
* @param string $endDate | |
*/ | |
public function setDates($startDate, $endDate) | |
{ | |
$start = $this->toCarbon($startDate); | |
$end = $this->toCarbon($endDate); | |
if ($end < $start) { | |
throw new Exception("End date {$endDate} cannot be lower than start date {$startDate}"); | |
} | |
$this->startDate = $startDate; | |
$this->endDate = $end->format('Y-m-d'); | |
} | |
/** | |
* Set scheduler recurring by month | |
* | |
* @param integer $months | |
* @return mixed | |
*/ | |
public function setRecurring($months, $startDate = null, $format = 'Y-m-d') | |
{ | |
if ($months > 12) { | |
throw new Exception("Scheduler recurring interval cannot be more than 12 months. {$months} given."); | |
} | |
$start = $this->toCarbon($this->startDate); | |
$this->recurrings = $this->getNextRecurringDate($start, $months); | |
return $this; | |
} | |
/** | |
* Get recurrings scheduler dates | |
* | |
* @return array | |
*/ | |
public function get() | |
{ | |
$recurrings = $this->recurrings; | |
$end = $this->toCarbon($this->endDate); | |
$last = $this->toCarbon(array_pop($recurrings)); | |
if ($last > $end) { | |
array_pop($this->recurrings); | |
} | |
return $this->recurrings; | |
} | |
/** | |
* Get next recurring dates | |
* | |
* @param Carbon\Carbon $base | |
* @param integer $months [description] | |
* @return array | |
*/ | |
protected function getNextRecurringDate(Carbon $base, $interval) | |
{ | |
$dates = array(); | |
list($year, $month, $day) = $this->calculateNextDate($base->format('Y-m-d'), $interval); | |
$next = $this->toCarbon("{$year}-{$month}-{$day}"); | |
$nextTotalDays = $next->format('t'); | |
$start = $this->toCarbon($this->startDate); | |
$end = $this->toCarbon($this->endDate); | |
$recurring = $base->addMonths($interval); | |
if ($recurring->month > $month) { | |
$nextDate = $this->toCarbon("{$year}-{$month}-{$nextTotalDays}"); | |
$diff = $recurring->diffInDays($nextDate); | |
$recurring->subDays($diff); | |
} | |
if ($recurring->day != $start->day and $recurring->month != 2) { | |
$recurring->day = $start->day; | |
} | |
if ($start->day == $start->lastOfMonth()->day) { | |
$recurring->day = $recurring->lastOfMonth()->day; | |
} | |
$dates[] = $recurring->format('Y-m-d'); | |
if ($recurring < $end) { | |
$dates[] = $this->getNextRecurringDate($recurring, $interval); | |
} | |
return array_flatten($dates); | |
} | |
/** | |
* Get next recurring date | |
* | |
* @param string $base | |
* @param integer $interval | |
* @return array | |
*/ | |
protected function calculateNextDate($base, $interval) | |
{ | |
list($year, $month, $day) = $this->toArray($base); | |
$nextMonth = $month + $interval; | |
if ($nextMonth > Carbon::MONTHS_PER_YEAR) { | |
$nextMonth = $nextMonth - Carbon::MONTHS_PER_YEAR; | |
$year = $year+1; | |
} | |
return array($year, (string) $nextMonth, '1'); | |
} | |
/** | |
* Convert MySQL DateTime format to array | |
* | |
* @param string $date | |
* @param string $seperator | |
* @return array | |
*/ | |
protected function toArray($date, $seperator = '-') | |
{ | |
$dates = explode($seperator, $date); | |
return $dates; | |
} | |
/** | |
* Convert date string to Carbon object | |
* | |
* @param string $date | |
* @return Carbon\Carbon | |
*/ | |
protected function toCarbon($date) | |
{ | |
$carbon = Carbon::createFromTimestamp(strtotime($date)); | |
return $carbon; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment