これはSOUSEI Technology アドベントカレンダー2020 15日目の記事です。

2/28と3/1どちらで祝うべきなのか

2/29生まれの人、閏年なら当日お祝いしてあげればいいのですが、閏年じゃないときはどうすればいいの?
ググってみました。

例年については、男女共に「2月28に祝う」という声が圧倒的。
https://cocoloni.jp/love/232234/

あとで祝われると「忘れてたでしょ?」ってなりそう
https://teratail.com/questions/145109

ということで2/28にお祝いします!🎉🎂
あとはデータを取得するだけ!

今日が誕生日の人を取得する

当日が2/28かつ閏年でないときに、追加で2/29のデータを取得してあげればOK!

$today = Carbon::now()->toDateString();
$users = User::whereDay('birthday', date('d', strtotime($today)))
    ->whereMonth('birthday', date('m', strtotime($today)))
    ->get();
if(date('m-d', strtotime($today)) == '02-28' && !date('L', strtotime($today))) {
    $users->merge(
        User::whereDay('birthday', 29)
        ->whereMonth('birthday', 2)
        ->get();
    );
}
return $users;

範囲指定(from〜to)で誕生日の人を取得する

これは指定された日付が閏年かどうか気にする必要はなく、toが2/28のときだけ考慮すればOK!

/**
 * 月日が日付範囲に含まれるスコープ
 *
 * @param Builder $query クエリ
 * @param string $column 対象カラム
 * @param Carbon $from 開始日
 * @param Carbon $to 終了日
 * @return Builder
 */
private function scopeWhereBetweenMonthAndDays($query, $column, $from, $to)
{
    // fromとtoの差が1年以上あるときはすべての日が対象になるのでクエリ追加不要(全データ取得する)
    if (!$to->diffInYears($from)) {
        $from_without_year = $from->format('m-d');
        // 閏年対応。2/28が指定された場合は2/29として、2/29のデータも取得対象とする
        $to_without_year = $to->format('m-d') == '02-28' ? '02-29' : $to->format('m-d');

        if ($from->year == $to->year) {
            $query = $query->whereRaw('DATE_FORMAT(' . $column . ',"%m-%d") >= "' . $from_without_year . '"')
                ->whereRaw('DATE_FORMAT(' . $column . ',"%m-%d") <= "' . $to_without_year . '"');
        } else {
            $query = $query->where(function ($q1) use ($from_without_year, $to_without_year) {
                $q1->orWhereRaw('DATE_FORMAT(' . $column . ',"%m-%d") >= "' . $from_without_year . '"')
                    ->orWhereRaw('DATE_FORMAT(' . $column . ',"%m-%d") <= "' . $to_without_year . '"');
            });
        }
    }
    return $query;
}

さいごに

僕の誕生日は3/3です!
プレゼント待ってます!