開始日から終了日までの期間を月ごとに分割するアルゴリズム
<?php
$samples=array();
//サンプル日付
$samples[]=array('2012/12/25','2015/5/12');
$samples[]=array('2012/12/12','2013/5/12');
$samples[]=array('2012/5/12','2012/9/13');
$samples[]=array('2012/11/12','2012/11/13');
$samples[]=array('2012/11/12','2012/11/12');
$samples[]=array('2012/12/12','2012/11/12');
$interval=3;
foreach($samples as $sample){
$start=$sample[0];
$end=$sample[1];
$rs=termMonthSplit($start,$end,$interval);
//結果出力
output($rs,$start,$end,$interval);
}
//結果出力
function output($rs,$start,$end,$interval){
echo "<hr>";
echo "{$start} ~ {$end} 間隔:{$interval}月毎<br>";
if(empty($rs)){
echo "<div class='result'>Null</div>";
}else{
foreach($rs as $i=> $ent){
echo "<div class='result'>{$i}: {$ent[0]} ~ {$ent[1]}</div>";
}
}
}
/**
* 開始日から終了日までの期間を月ごとに分割する。
* 月間隔を指定するなら季節ごとの分割も再現できる。(1月を基準とし、月間隔値の倍数で分割)
* @param $start 開始日
* @param $end 終了日
* @param $interval 月間隔
* @return 期間分割リスト
*/
function termMonthSplit($start,$end,$interval){
//Y-m-d形式にする。
$start=date('Y-m-d',strtotime($start));
$end=date('Y-m-d',strtotime($end));
// 開始日を年月日に分割
$start_y=date('Y', strtotime($start));
$start_m=date('m', strtotime($start));
// 終了日を年月日に分割
$end_y=date('Y', strtotime($end));
$end_m=date('m', strtotime($end));
$m1=0; // 月値1
$m2=0; // 月値2
$list=array();
// 開始年から終了年までの年ループ
for($y=$start_y ; $y <= $end_y ; $y++){
// 年ループは初周回であるか?
if($y == $start_y){
$m1 = $start_m; // 月ループの月値1に開始月をセット
}else{
$m1 = 1; // 月ループの月値1に1をセット
}
// 年ループは最周回であるか?
if($y == $end_y){
$m2 = $end_m;// 月ループの月値2に終了月をセット
}else{
$m2 = 12; // 月ループの月値2に12
}
// 月ループ 月値1から月値2までループ
for($m=$m1 ; $m <= $m2 ; $m++){
// 年ループの初周回且つ、月ループの初周回であるか?
if($y == $start_y && $m == $m1){
$list[]=$start; // リストに開始日を追加
}
// 年ループの最周回且つ、月ループの最周回であるか?
if($y == $end_y && $m == $m2 ){
$list[]=$end;// リストに最終日を追加
}
// 月値は月間隔の倍数であるか?
if(($m % $interval) == 0){
$str_ym1=$y.'-'.$m.'-1';
// 月値の月末を取得し、リストに追加
$yml = date('Y-m-t',strtotime($str_ym1));
$list[]=$yml;
// 次月の月初を取得し、リストに追加
if($m == 12){
$str_ym2=($y + 1).'-1-1';
}else{
$str_ym2=$y.'-'.($m + 1).'-1';
}
$ym1=date('Y-m-d',strtotime($str_ym2));
$list[]=$ym1;
}
}
}
$list2=array_chunk($list,2);//開始年と終了年のリストになるよう構造変換
return $list2;
}
?>
結果出力
2012/12/25 ~ 2015/5/12 間隔:3月毎
0: 2012-12-25 ~ 2012-12-31
1: 2013-01-01 ~ 2013-03-31
2: 2013-04-01 ~ 2013-06-30
3: 2013-07-01 ~ 2013-09-30
4: 2013-10-01 ~ 2013-12-31
5: 2014-01-01 ~ 2014-03-31
6: 2014-04-01 ~ 2014-06-30
7: 2014-07-01 ~ 2014-09-30
8: 2014-10-01 ~ 2014-12-31
9: 2015-01-01 ~ 2015-03-31
10: 2015-04-01 ~ 2015-05-12
2012/12/12 ~ 2013/5/12 間隔:3月毎
0: 2012-12-12 ~ 2012-12-31
1: 2013-01-01 ~ 2013-03-31
2: 2013-04-01 ~ 2013-05-12
2012/5/12 ~ 2012/9/13 間隔:3月毎
0: 2012-05-12 ~ 2012-06-30
1: 2012-07-01 ~ 2012-09-13
2: 2012-09-30 ~ 2012-10-01
2012/11/12 ~ 2012/11/13 間隔:3月毎
0: 2012-11-12 ~ 2012-11-13
2012/11/12 ~ 2012/11/12 間隔:3月毎
0: 2012-11-12 ~ 2012-11-12
2012/12/12 ~ 2012/11/12 間隔:3月毎
Null