在 laravel 中查找未来 7 天内过生日的客户

Kar*_*hik 1 php laravel laravel-5.5 laravel-5.8

我需要获取 Laravel 中未来 7 天内过生日的客户列表。我使用以下查询。该查询还显示已过的生日。

 $customerslist=Customers::WhereRaw('DAYOFYEAR(curdate()) <= DAYOFYEAR(date_of_birth) AND DAYOFYEAR(curdate()) + 7 >=  dayofyear(date_of_birth)' )->OrderBy(DB::raw("DAYOFYEAR(date_of_birth)"),'ASC')->get();
Run Code Online (Sandbox Code Playgroud)

我使用下面列出的查询,但缺少一些客户 在此输入图像描述

失踪的顾客

在此输入图像描述

Mal*_*xie 5

我发现使用 DAYOFYEAR 方法进行原始查询非常优雅,因为它消除了不同出生年份的所有问题。然而,它不能很好地处理闰年。

我发现 BETWEEN 和 DATE_FORMAT 的组合会产生正确的结果。它确实需要进行检查来处理岁月边缘的情况。

以下是如何在模型范围内实现此示例的示例:

public function scopeBirthDayBetween ($query, Carbon $from, Carbon $till)
{
    $fromMonthDay = $from->format('m-d');
    $tillMonthDay = $till->format('m-d');
    if ($fromMonthDay <= $tillMonthDay) {
        //normal search within the one year
        $query->whereRaw("DATE_FORMAT(birthdate, '%m-%d') BETWEEN '{$fromMonthDay}' AND '{$tillMonthDay}'");
    } else {
        //we are overlapping a year, search at end and beginning of year
        $query->where(function ($query) use ($fromMonthDay, $tillMonthDay) {
            $query->whereRaw("DATE_FORMAT(birthdate, '%m-%d') BETWEEN '{$fromMonthDay}' AND '12-31'")
                ->orWhereRaw("DATE_FORMAT(birthdate, '%m-%d') BETWEEN '01-01' AND '{$tillMonthDay}'");
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

$users = User::birthDayBetween(Carbon::now(), Carbon::now()->addWeek())->get()
Run Code Online (Sandbox Code Playgroud)

要添加生日而不是出生日期的排序,更多原始查询和 DATE_FORMAT 可以提供帮助。

$users = User::query()
    ->birthDayBetween($from, $till)
    ->orderByRaw("DATE_FORMAT(birth_date,'%m%d')")
    ->orderByRaw("DATE_FORMAT(birth_date,'%y') desc")
    ->orderBy('first_name')
    ->get();
Run Code Online (Sandbox Code Playgroud)

注意:查看年份边缘时,排序将会关闭,因为生日在明年年初的用户将首先排序。我选择在前端解决这个问题。