WordPressやPHPで毎月同じ日を指定して処理したいことがあります。
うるう年、30日、31日まである月がバラバラなので、単純にUNIXタイムに30日(25692000秒)足しただけでは、毎月同じ日になりません。
また、PHPにはstrtotime('+1month')がありますが、30日や31日の日数が考慮されていないのでうまく動作しません。
そういう場合に、毎月同じ日を指定する方法を紹介します。
毎月同じ日に処理を実行するための日付作成関数
下記は、「入力した日付」から「翌月以降の同じ日付」を返す関数のサンプルです。
処理を実行した日を入力すれば、翌月実行する日を返してくれます。
checkdate関数を使って、生成した日付が有効かをチェックして、ダメだった場合は次に有効な月を探すようにしています。
<?php
//日付と時間
$post_date= date('Ymd');
$post_time = date('His');
//次に有効な月の〇日をunixtimeで返す関数
$next_schedule = next_schedule_monthly ( $post_date, $post_time );
function next_schedule_monthly ( $post_date, $post_time ) {
//01234567
//YYYYMMDD
$datetime['year'] = (int)substr($post_date, 0, 4);
$datetime['month'] = (int)substr($post_date, 4, 2);
$datetime['day'] = (int)substr($post_date, 6, 2);
//012345
//HHMMSS
$datetime['second'] = 0;
$datetime['minute'] = (int)substr($post_time, 2, 2);
$datetime['hour'] = (int)substr($post_time, 0, 2);
$check_month = $datetime['month'];
$check_flag = true;
for($i=1; $i<13; $i++) {
//翌月作成
$check_month++;
//12月以内に変更する
if($check_month >= 13) {
$check_month = $check_month - 12;
if($check_flag) {
$datetime['year'] = $datetime['year'] + 1;
$check_flag = false;
}
}
//正しい日付かをチェックする
if( checkdate( $check_month, $datetime['day'], $datetime['year'] ) ) {
break;
}
}
//UTC+9とUTCに変換
$schedule_time['utc_jp'] = mktime($datetime['hour'], $datetime['minute'], $datetime['second'], $check_month, $datetime['day'], $datetime['year']);
$schedule_time['utc'] = $schedule_time['utc_jp'] - 32400;
return $schedule_time;
}
有効な日付のサンプル
- 入力した日付が「1月31日」の場合、次に有効な日付は「3月31日」
- 入力した日付が「3月31日」の場合、次に有効な日付は「5月31日」
- 入力した日付が「2022年12月31日」の場合、次に有効な日付は「2023年1月31日」
上記の関数では、入力(日本時間)に対して、返り値を「UTC」と「日本時間(UTC+9)」の2つを配列で返しています。
【まとめ】毎月同じ日に処理を実行したい時
うるう年や、30日、31日まである月がバラバラなので、単純にUNIXタイムに30日(25692000秒)足しただけでは、同じ日にできない。
また、PHPのstrtotime('+1month')でも正常に動作しないので、同じ日付を返す関数の作成が必要です。