前提条件
よくコンテンツの定期課金にて、入会日を毎月の決済日とする仕様があります。
15日に入会した場合、その人の課金日は15日という仕様。あるあるです。
では、もちょっと掘り下げてみましょう。
サンプルストーリー
例)Aさんが2019年1月20日に入会した場合、Aさんの毎月の課金日は20日となります。
ここまではOKですよね。
例)、Bさんが2019年1月31日に入会した場合、Bさんの毎月の課金日は31日ですが
2019年2月31日は存在しない為、Bさんの2月の課金日は28日となります。
当然ですが、仮にうるう年であった場合でも、問題なく算出できる処理を書きます。
年をまたいだ時の処理も考慮します。
ポイント
ここでのポイントは
月と日を分けて考えることです。
public function serviceStartAt()
{
//一か月後を算出する
// $year = 2018;
// $month = 11;
// $day = 31;
//本日の年月を算出する
$year = date('Y', time());
$month = date('m', time());
$day = date('d', time());
//月だけを算出する
//月が11のときまで、1を加算する 12のときは1にする
if($month == '12'){
++$year;
$month = 1;
}
++$month;
//実在する年月日かをチェックし、存在しなければ1日づつ減らす
$i = $day;
while($i <= 31){
//実在する日があるかをチェックする
$checkDate = checkdate($month, $i, $year);
if(!empty($checkDate))
break;
$i--;
}
$format = "%s-%s-%s";
$oneMonthLater = sprintf($format, $year, $month, $i);
return $oneMonthLater;
}