社内で使用するサービスの改修を行う中で
定期的な予約を行う仕様があるのですが
定期的な予約の期間も仕様で定められていて
その予約も毎週1回の指定しか出来なかったので
今回、n週間にn度、nヶ月に1度といった仕様を追加しました。
より良い処理があればコメント頂けると嬉しいです!
// 月ごと開催のテンプレート
/*
*return 'Y-m-d'
*/
function monthTemplate($end_date, $month_week, $week_count, $period) {
$start = date("Y-m-d");
$end = date('Y-m-d', strtotime($end_date . 'last day of this month'));
$weekly = $month_week;
$d_start = strtotime($start . " first day of 0 month");
$d_end = strtotime($end . " first day of 1 month");
$target = [[$weekly, $week_count]];
$list = [];
$d = $d_start;
$c = 0;
while ($d < $d_end) {
foreach ($target as $val) {
$list[] = date("Y-m-d", strtotime(date("Y-m-d", $d) . sprintf("first %s of 0 month +%d week", $val[0], $val[1] - 1)));
}
$d = strtotime(date("Y-m-d", $d) . '+' . $period . 'month');
}
sort($list);
$list = array_filter($list, function($x) use($start, $end) {
return $x >= $start and $x <= $end;
});
return $list;
}
// 週間ごと開催のテンプレート
function weekTemplate($end_date, $weekly, $period) {
$start = date('Y-m-d');
$target_week = date('w', strtotime($start));
$target_sunday = date("Y-m-d", strtotime("-" . $target_week . "day", strtotime($start)));
$start_monday = date('Y-m-d', strtotime('+ 1 week', strtotime($target_sunday)));
$end = $end_date;
$d_end = strtotime($end . 'last day of this month');
$list = [];
$d = strtotime($start_monday);
while ($d < $d_end) {
foreach ($weekly as $val) {
$day = date('Y-m-d', strtotime('next ' . $val . date('Y-m-d', $d)));
$list[] = $day;
}
$d = strtotime(date('Y-m-d', $d) . '+' . $period . 'week');
}
sort($list);
$list = array_filter($list, function($x) use($start) {
return $x >= $start;
});
return $list;
}
つまづいた点
コードの中に文章がある?となって調べました。
公式→https://www.php.net/manual/ja/datetime.formats.relative.php
これ→**'last day of this month'**
$end = date('Y-m-d', strtotime($end_date . 'last day of this month'));
解釈として
last day of this month → 月の最終日を指定
first day of 1 month → 月の最初の日を指定
正直まだ雰囲気でしか理解していないのでもっと相対的な書式を使って覚えていきたい。
今回参考にした内容 → https://teratail.com/questions/191105
こちらでは第n曜日と指定をして取得しているので
それを改修してみたのだが
if(date("Y-m",$d)==substr($day,0,7)) $list[]=$day;
こちらの処理をいまいち理解しておらず
2週に一回の指定をした際に月を跨ぐと
第1週目の取得されるであろう日にちが取得できずにいて悩んだが
きちんとコードを読めば、また参考した内容の求めている内容を理解していれば
すぐに気付けただろう箇所
僕なりの解釈で言うと
毎月の第n曜日を指定するので毎月の終わりで締めないと
第n曜日がずれていってしまうので
このif文で条件をつけている
改めて気づいたこと
再改修したことがあれば更新します。