目的
元々は、12月のスケジュールから空白期間を見つけるために必要になった。
検索してみたところ似たようなものがなかなか見つからなかったので自作。
例
12月のスケジュールが
- 12月01日 0:00:00~12月20日 23:59:59
- 12月22日 0:00:00~12月31日 23:59:59
である場合、空いている期間は、
- 12月21日 0:00:00~12月21日 23:59:59 になる。
使い方
調べたい期間を設定
$objDateSplit = new DateSplit(new DateTime('2017-12-01 00:00:00'), new DateTime('2017-12-31 23:59:59'));
期間から除外するスケジュールを指定
$objDateSplit->splitPeriod(new DateTime('2017-12-01 00:00:00'), new DateTime('2017-12-20 23:59:59'));
$objDateSplit->splitPeriod(new DateTime('2017-12-22 00:00:00'), new DateTime('2017-12-31 23:59:59'));
出力
foreach ($objDateSplit as $aryBlankRow) {
printf("%s ~ %s\n", $aryBlankRow[0]->format('Y-m-d H:i:s'), $aryBlankRow[1]->format('Y-m-d H:i:s'));
}
#[結果] 2017-12-21 00:00:00 ~ 2017-12-21 23:59:59
クラス
class DateSplit implements IteratorAggregate
{
/**
* 期間一覧
*
* @var array int
*/
protected $aryPeriod = [];
/**
* コンストラクタ
*
* @param \DateTime 全体期間開始日
* @param \DateTime 全体期間終了日
*/
public function __construct(\DateTime $objDateFrom, \DateTime $objDateTo) {
$this->aryPeriod[] = [$objDateFrom->getTimestamp(), $objDateTo->getTimestamp()];
}
public function getIterator() {
$aryResult = [];
foreach ($this->aryPeriod as $aryPeriodRow) {
$aryResult[] = [
new \DateTime(date('Y-m-d H:i:s', $aryPeriodRow[0])),
new \DateTime(date('Y-m-d H:i:s', $aryPeriodRow[1])),
];
}
return new ArrayIterator($aryResult);
}
/**
* 期間を分割する
*
* @param \DateTime 分割開始期間
* @param \DateTime 分割終了期間
*/
public function splitPeriod(\DateTime $objDatePeriodFrom, \DateTime $objDatePeriodTo) {
$aryResult = [];
$numPeriodFrom = $objDatePeriodFrom->getTimestamp();
$numPeriodTo = $objDatePeriodTo->getTimestamp();
foreach ($this->aryPeriod as $aryBasePeriod) {
$aryResultTmp = [];
$numBaseFrom = $aryBasePeriod[0];
$numBaseTo = $aryBasePeriod[1];
if ($numBaseFrom < $numPeriodFrom && $numBaseTo > $numPeriodFrom) {
$aryResultTmp[] = [$numBaseFrom, $numPeriodFrom - 1];
}
if ($numBaseFrom < $numPeriodTo && $numBaseTo > $numPeriodTo) {
$aryResultTmp[] = [$numPeriodTo + 1, $numBaseTo];
}
if (count($aryResultTmp) === 0 && !($numBaseFrom === $numPeriodFrom && $numBaseTo === $numPeriodTo)) {
$aryResultTmp[] = [$numBaseFrom, $numBaseTo];
}
$aryResult = array_merge($aryResult, $aryResultTmp);
}
$this->aryPeriod = $aryResult;
}
}