Laravel $q->где()между датами


Я пытаюсь заставить свой cron получать только Projects, которые должны повториться/обновиться в течение следующих 7 дней, чтобы отправлять электронные письма с напоминаниями. Я только что обнаружил, что моя логика не совсем работает.

В настоящее время у меня есть запрос:

$projects = Project::where(function($q){
    $q->where('recur_at', '>', date("Y-m-d H:i:s", time() - 604800));
    $q->where('status', '<', 5);
    $q->where('recur_cancelled', '=', 0);
});

Однако я понял, что мне нужно сделать что-то вроде:

Psudo SQL:

SELECT * FROM projects WHERE recur_at > recur_at - '7 days' AND /* Other status + recurr_cancelled stuff) */

Как бы я сделал это в Laravel 4, и используя тип данных DATETIME, я делал такие вещи только с использованием временных меток.

Обновление:

Удалось решить эту проблему после использования следующего кода, Stackoverflow также помогает, когда вы можете извлекать фрагменты кода и рассматривать их вне контекста.

$projects = Project::where(function($q){
    $q->where(DB::raw('recur_at BETWEEN DATE_SUB(NOW(), INTERVAL 7 DAY) AND NOW()'));
    $q->where('status', '<', 5);
    $q->where('recur_cancelled', '=', 0);
});

Обновленный вопрос: Есть ли лучший способ сделать это в Laravel/Eloquent?

Обновление 2:

Первое решение оказалось неправильным после дальнейшего тестирования, теперь я решил и протестировал следующее решение:

$projects = Project::where(function($q){
    $q->where('recur_at', '<=', Carbon::now()->addWeek());
    $q->where('recur_at', '!=', "0000-00-00 00:00:00");
    $q->where('status', '<', 5);
    $q->where('recur_cancelled', '=', 0);
});
Author: Jono20201, 2014-07-18

4 answers

Вы можете связать свои where напрямую, без function(q). В laravel также есть хороший пакет для обработки дат, называемый Carbon. Таким образом, вы могли бы сделать что-то вроде:

$projects = Project::where('recur_at', '>', Carbon::now())
    ->where('recur_at', '<', Carbon::now()->addWeek())
    ->where('status', '<', 5)
    ->where('recur_cancelled', '=', 0)
    ->get();

Просто убедитесь, что вам требуется углерод в composer и вы используете пространство имен Carbon (используйте Carbon\Carbon;), и это должно сработать.

РЕДАКТИРОВАТЬ: Как сказал Джоэл, вы могли бы сделать:

$projects = Project::whereBetween('recur_at', array(Carbon::now(), Carbon::now()->addWeek()))
    ->where('status', '<', 5)
    ->where('recur_cancelled', '=', 0)
    ->get();
 57
Author: Tom, 2017-05-23 10:31:20

Не хотел связываться с углеродом. Итак, вот мое решение

$start = new \DateTime('now');
$start->modify('first day of this month');
$end = new \DateTime('now');
$end->modify('last day of this month');

$new_releases = Game::whereBetween('release', array($start, $end))->get();
 12
Author: Edmund Sulzanok, 2015-03-02 13:01:56

@Tom: Вместо использования "сейчас" или "Addweek", если мы указываем дату в следующем формате, это не дает правильных записей

$projects = Project::whereBetween('recur_at', array(new DateTime('2015-10-16'), new DateTime('2015-10-23')))
->where('status', '<', 5)
->where('recur_cancelled', '=', 0)
->get();

Это дает записи, имеющие форму даты 2015-10-16, меньше, чем 2015-10-23. Если стоимость recur_at является 2015-10-23 00:00:00 тогда только , он показывает этой записи еще, если это 2015-10-23 12:00:45 тогда это не показаны.

 3
Author: Jaykumar Patil, 2015-10-27 09:27:35

Отредактировано: Пожалуйста, обратите внимание, что
whereBetween('date',$start_date,$end_date)
включает в себя первое свидание.

 -1
Author: Edwin M, 2017-06-13 20:05:19