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, я делал это только с помощью меток времени.
Update:
Чтобы решить эту проблему после использования следующего кода, 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);
});
Ответы
Ответ 1
Вы можете напрямую связать свой 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();
Просто убедитесь, что вам нужен Carbon в композиторе, и вы используете пространство имен Carbon (используйте Carbon\Carbon;), и оно должно работать.
EDIT:
Как Джоэл сказал, вы могли бы сделать:
$projects = Project::whereBetween('recur_at', array(Carbon::now(), Carbon::now()->addWeek()))
->where('status', '<', 5)
->where('recur_cancelled', '=', 0)
->get();
Ответ 2
Не хотелось путаться с углеродом. Итак, мое решение
$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();
Ответ 3
@Tom: вместо использования "now" или "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, то только он показывает, что запись
else if 2015-10-23 12:00:45, тогда он не отображается.
Ответ 4
Отредактировано: Пожалуйста, обратите внимание, что whereBetween('date',$start_date,$end_date)
включает первую дату.