やりたいこと
タイトル通り。
例:2018年7月の第3週って何日~何日なの?
関数化
/**
* XXXX年XX月の第N週は、何日から何日までか
*
* @param string $ym 対象年月。YYYY-MM形式
* @param int $n 取得したい週
* @param bool $aroundMonthFlg 前後の月を含めて算出する場合のみtrue
* @param bool $startMondayFlg 月曜始まりとしたい場合のみtrue
* @return array
*/
function getWeekBothEnds($ym, $n, $aroundMonthFlg = false, $startMondayFlg = false) {
// 第1週最終曜日の計算用(デフォルトは土曜、月曜始まりの場合は日曜)
$weekEnd = 6;
if ($startMondayFlg === true) {
$weekEnd = 7;
}
// 月初(1日)の曜日を取得
$weekNo = date('w', strtotime('first day of ' . $ym));
// 曜日番号の差から第1週最終曜日の日付を算出する
$firstEndDay = $weekEnd - $weekNo + 1;
if ($firstEndDay === 8) {
// 1日が日曜かつ、月曜始まりの場合のみ8になってしまうので調整
$firstEndDay = 1;
}
$firstEndStamp = strtotime($ym . '-' . sprintf('%02d', $firstEndDay));
// 第1週最終曜日の日付 - 6 = 第1週の最初の日付
$firstStartStamp = $firstEndStamp - (6 * 24 * 60 * 60);
// 第1週の開始日と終了日が分かっているので、これを第N週にスライド
$startStamp = $firstStartStamp + (($n - 1) * 7 * 24 * 60 * 60);
$endStamp = $firstEndStamp + (($n - 1) * 7 * 24 * 60 * 60);
// 前後の月を含まない場合
if ($aroundMonthFlg === false) {
// 週初めが先月やんけ!
if (date('Y-m', $startStamp) !== $ym) {
// 1日にしといたろ
$startStamp = strtotime('first day of ' . $ym);
}
// 週終わりが来月やんけ!
if (date('Y-m', $endStamp) !== $ym) {
// 末の日にしといたろ。しゃーなしやで!
$endStamp = strtotime('last day of ' . $ym);
}
}
return array(
// 開始
$startStamp,
// 終了
$endStamp,
);
}
実行
// 今年の7月第3週は、7/15(日)~7/21(土)
$item = getWeekBothEnds('2018-07', 3);
echo date('Y/m/d', $item[0]) . ' ~ ' . date('Y/m/d', $item[1]) . "\n";
// -> 「2018/07/15 ~ 2018/07/21」
// 今年の6月第1週は、6/1(金)~6/2(土)
$item = getWeekBothEnds('2018-06', 1);
echo date('Y/m/d', $item[0]) . ' ~ ' . date('Y/m/d', $item[1]) . "\n";
// -> 「2018/06/01 ~ 2018/06/02」
// 今年の6月第1週、前月も含めると5/27(日)~6/2(土)
$item = getWeekBothEnds('2018-06', 1, true);
echo date('Y/m/d', $item[0]) . ' ~ ' . date('Y/m/d', $item[1]) . "\n";
// -> 「2018/05/27 ~ 2018/06/02」
// 今年の9月第6週は、9/30(日)のみ
$item = getWeekBothEnds('2018-09', 6);
echo date('Y/m/d', $item[0]) . ' ~ ' . date('Y/m/d', $item[1]) . "\n";
// -> 「2018/09/30 ~ 2018/09/30」
// 今年の9月第6週は、次月を含めると9/30(日)~10/6(土)
$item = getWeekBothEnds('2018-09', 6, true);
echo date('Y/m/d', $item[0]) . ' ~ ' . date('Y/m/d', $item[1]) . "\n";
// -> 「2018/09/30 ~ 2018/10/06」