Laravelで1年以内のバリデーションを実装する (うるう年を考慮)

2020年11月8日日曜日

Carbon Laravel うるう年 バリデーション

t f B! P L

# 内容

Laravelで日付操作を行う際は、Carbonを利用されるかと思います。
Carbonには、diffInYears()という関数が用意されており、年単位の差を判定してくれます。 以下に例を示します。

 $case1 = new Carbon('2020-01-01');
 $case2 = new Carbon('2020-12-31');

 \Log::debug('差分は ' . $case1->diffInYears($case2) . ' です');
 
 $case3 = new Carbon('2020-01-01');
 $case4 = new Carbon('2021-01-01');
 
 \Log::debug('差分は ' . $case3->diffInYears($case4) . ' です');

 $case5 = new Carbon('2019-03-01');
 $case6 = new Carbon('2020-02-29');

 \Log::debug('差分は ' . $case5->diffInYears($case6) . ' です');
 
 > local.DEBUG: 差分は 0 です
 > local.DEBUG: 差分は 1 です
 > local.DEBUG: 差分は 1 です

上述の結果から、お気づきかもしれませんが、「2019/03/01」~「2020/02/29」の差分を1年と判定してしまいます。
厳密に1年のバリデーションを行いたい場合はdiffInYearsではうるう年を考慮することができません。


# 解決策

力技になってしまうのですが、以下のようにうるう年(02/29)を除外してカウントするカスタムバリデーションを作成しました。

// 日付Fromと日付Toを比較して1年を超えるかチェック
Validator::extend(
    'withinOneYear',
    function ($attribute, $value, $parameters, $validator) {
        $dateFrom = new Carbon($value);
        $dateTo = new Carbon($parameters[0]);
        // うるう年の対策処理
        $diffDays = Carbon::parse($dateFrom)->diffInDaysFiltered(function (Carbon $date) {
            // 2/29を除外
            return $date->format('m-d') != '02-29';
        },
        Carbon::parse($dateTo->addDay(1)));
        return !($diffDays > 365);
    }
);

注目の投稿

composer.lockはGit管理すべき話

# 背景 # 結論 # composer installとcomposer updateの違い # 背景 仕事では主にLaravelを使用して開発を行っている。 ソースコードはGitでバージョン管理を行い、compose...

プロフィール

7年ほど中小企業でSIerとして働いていました。 現在は個人事業主としてPHP, Javascriptの企業案件をメインに受けています。 最近はポケモンカードの開封にはまっています。

アーカイブ

このブログを検索

QooQ