PHPで隔週の隔週水曜日の判定を行いたいのですが、良い方法ありますか？

例えば2021年は水曜日1/6から始まります。  
06から隔週で続いている水曜日を取得したいのですが・・・  
＊2021年に限らず ある起点の水曜日を指定したら、その水曜日の隔週かを調べたいです。  
e.g 21.Jul.2021を起点として "4.Aug.2021"ならばtrueといった形です。

↓日付データが来たら、1/6から始まっている隔週かどうか判定できるような仕組みが欲しいです。何か良いスマートな方法ありますか？

```

    if(date(2021-01-06)
    {
    true
    }
    if(date(2021-01-13)
    {
    false
    }
    if(date(2021-01-20)
    {
    true
    }
    
```
CC BY-SA 4.0
2021-07-18T08:34:44.237
78267
2021-07-18T13:15:48.210
2021-07-18T12:18:03.880
45215
45215
question
php
隔週の特定曜日の判定
判定したい日付は、 「2021年内の水曜日だと既にわかっている日付」で良いでしょうか？  
（もし違っていたら、質問の本文の条件をより具体的に編集してください。）

php の 日付のフォーマットには、 [ISO-8601 月曜日に始まる年単位の週番号 を示す
'W'](https://www.php.net/manual/ja/datetime.format.php) が存在します。  
この値が奇数か偶数か見れば、お望みの結果を得られそうです。

```

    $dates = [
        "2021-01-06",
        "2021-01-13",
        "2021-01-20",
        "2021-01-27",
        "2021-02-03",
    ];
    function is_odd_week($date_str) {
        return (int)(new DateTime($date_str))->format("W") % 2 === 1 ? "true" : "false";
    }
    
    print_r(array_map('is_odd_week', $dates));
    
```

結果

```

    Array
    (
        [0] => true
        [1] => false
        [2] => true
        [3] => false
        [4] => true
    )
    
```

→ 実行例: <https://paiza.io/projects/h87WnX-J4p2huXORTkz_gA>

年によって 1月1日 の曜日が変わるので、他の年も扱いたい場合は、 その年の初めの1月1日の曜日が "月" または "火水" または "木金土日"
どちらであるかで、場合分けするのが手っ取り早いでしょう。  
このとき、 その年の最初の月曜日より前の日付は、旧年最終週と扱われてしまうので、その年が "火水" 始まりの場合の 1週目 の判定は少し工夫が必要です。
CC BY-SA 4.0
2021-07-18T09:21:53.047
78269
2021-07-18T09:38:41.867
2021-07-18T09:38:41.867
8237
8237
78267
answer
以下は Carbon を使う方法です。

```

    <?php
    require 'Carbon/autoload.php';
    
    use Carbon\Carbon;
    
    $day = 'wed';
    $first = Carbon::parse("first {$day} of 2021-01");
    
    // test data
    $dates = array(
      date('2021-01-06'), date('2021-01-13'),
      date('2021-01-20'), date('2021-09-22'),
      date('2021-12-08'), date('2022-08-03'),
    );
    
    foreach ($dates as $date) {
      $diff = Carbon::parse($date)->diffInDays($first);
      echo "{$date} is " . ($diff % 14 ? 'false' : 'true') . PHP_EOL;
    }
    
    // 実行結果
    2021-01-06 is true
    2021-01-13 is false
    2021-01-20 is true
    2021-09-22 is false
    2021-12-08 is true
    2022-08-03 is true
    
```
CC BY-SA 4.0
2021-07-18T09:33:22.563
78270
2021-07-18T09:33:22.563
47127
78267
answer
> ＊2021年に限らず ある起点の水曜日を指定したら、その水曜日の隔週かを調べたいです。  
>  e.g 21.Jul.2021を起点として "4.Aug.2021"ならばtrueといった形です。

ということでしたら、 日付の差を計算して 14 で割り切れるかで判定して良さそうです。

既に Carbon で書いた例を他の回答者が書かれていますが、 起点となる日付が明確になっているなら、 DateTime だけでも計算できます。

```

    $is_odd_week_func_a = function ($date_str) {
        $standard = new DateTime("2021-01-06");
        $is_odd_week = (int)(new DateTime($date_str))->diff($standard)->format("%a") % 14 === 0;
        return $date_str . ' is ' . ($is_odd_week ? "true" : "false");
    };
    $a_dates = [
        "2021-01-06",
        "2021-01-13",
        "2021-01-20",
        "2021-01-27",
        "2021-02-03",
    ];
    print_r(array_map($is_odd_week_func_a, $a_dates));
    
    $is_odd_week_func_b = function ($date_str) {
        $standard = new DateTime("2021-01-06");
        $is_odd_week = (int)(new DateTime($date_str))->diff($standard)->format("%a") % 14 === 0;
        return $date_str . ' is ' . ($is_odd_week ? "true" : "false");
    };
    $b_standard = "2021-07-21";
    $b_dates = [
        "2021-07-21",
        "2021-07-28",
        "2021-08-04",
        "2021-08-11",
        "2021-08-18",
    ];
    print_r(array_map($is_odd_week_func_b, $b_dates));
    
```

結果

```

    Array
    (
        [0] => 2021-01-06 is true
        [1] => 2021-01-13 is false
        [2] => 2021-01-20 is true
        [3] => 2021-01-27 is false
        [4] => 2021-02-03 is true
    )
    Array
    (
        [0] => 2021-07-21 is true
        [1] => 2021-07-28 is false
        [2] => 2021-08-04 is true
        [3] => 2021-08-11 is false
        [4] => 2021-08-18 is true
    )
    
```

→ クロージャ使った実行例: <https://paiza.io/projects/rG657Igp28cThFDCGW6PYA>
CC BY-SA 4.0
2021-07-18T13:15:48.210
78277
2021-07-18T13:15:48.210
8237
78267
answer