¿Cómo consultar entre dos fechas usando Laravel y Eloquent?

122

Estoy intentando crear una página de informe que muestre informes desde una fecha específica hasta una fecha específica. Aquí está mi código actual:

$now = date('Y-m-d');
$reservations = Reservation::where('reservation_from', $now)->get();

Lo que esto hace en SQL simple es select * from table where reservation_from = $now.

Tengo esta consulta aquí, pero no sé cómo convertirla en una consulta elocuente.

SELECT * FROM table WHERE reservation_from BETWEEN '$from' AND '$to

¿Cómo puedo convertir el código anterior en una consulta elocuente? Gracias de antemano.

wobsoriano
fuente
cuál es el formato de fecha en reservation_from. puede usar los valores de carbono basados ​​en eso.
Athi Krishnan
El formato de fecha es TIMESTAMP @AthiKrishnan
wobsoriano
4
sería como Reservation::where('reservation_from', '>=', Carbon::createFromDate(1975, 5, 21);) ->where('reservation_from', '<=', Carbon::createFromDate(2015, 5, 21);)->get(),;
Athi Krishnan

Respuestas:

246

El whereBetweenmétodo verifica que el valor de una columna esté entre dos valores.

$from = date('2018-01-01');
$to = date('2018-05-02');

Reservation::whereBetween('reservation_from', [$from, $to])->get();

En algunos casos, es necesario agregar un rango de fechas de forma dinámica. Según el comentario de @Anovative , puede hacer esto:

Reservation::all()->filter(function($item) {
  if (Carbon::now->between($item->from, $item->to) {
    return $item;
  }
});

Si desea agregar más condiciones, puede usar orWhereBetween. Si desea excluir un intervalo de fechas, puede usar whereNotBetween.

Reservation::whereBetween('reservation_from', [$from1, $to1])
  ->orWhereBetween('reservation_to', [$from2, $to2])
  ->whereNotBetween('reservation_to', [$from3, $to3])
  ->get();

Otras cláusulas útiles donde: whereIn, whereNotIn, whereNull, whereNotNull, whereDate, whereMonth, whereDay, whereYear, whereTime, whereColumn, whereExists, whereRaw.

Documentos de Laravel sobre las cláusulas Where.

Peter Kota
fuente
¿Cómo se manejaría esto si $fromy $tofueran fechas dinámicas que pertenecen al modelo? Al igual que en existe una effective_aty expires_atcampos y quiero consulta para ver si el elemento actual es dentro de ese rango. Intenté each()con un if que se usa Carbon::now()->between( ... ), sin embargo, todavía devuelve todos los resultados.
Rockin4Life33
4
EDITAR para mi comentario anterior: Pasado por alto filter(), eso funcionó. MyModel::all()->where('column', 'value')->filter(function ($item) { if (Carbon::now->between($item->effective_at, $item->expires_at)) { return $item; } })->first();
Rockin4Life33
1
@Anovative gracias por su útil comentario. Actualizaré mi respuesta según tu comentario.
Peter Kota
solo dará a partir del registro de fecha.
Muhammad
1
Hay un problema con el segundo método. Cargará todos los registros de la base de datos a la memoria y solo luego realizará el filtrado.
Jino Antony
12

Otra opción si su campo es en datetimelugar de date( aunque funciona para ambos casos ):

$fromDate = "2016-10-01";
$toDate   = "2016-10-31";

$reservations = Reservation::whereRaw(
  "(reservation_from >= ? AND reservation_from <= ?)", 
  [$fromDate." 00:00:00", $toDate." 23:59:59"]
)->get();
tomloprod
fuente
1
técnicamente, no tendría que ser $ toDate. "23: 59.59.999"?
stevepowell2000
@ stevepowell2000 Depende de tu base de datos, en mi caso almacenamos la fecha con este formato 'AAAA-MM-DD HH: MM: SS' en un campo mysql de fecha y hora, sin precisión de microsegundos. Información relacionada: dev.mysql.com/doc/refman/8.0/en/datetime.html
tomloprod
Gran punto. Así que si se tratara de un campo de fecha y hora o marca de tiempo que puede ir todo el camino hasta el 23: 59: 59.999999 "valor de una fecha y hora o marca de tiempo puede incluir una parte de las fracciones de segundo se arrastra hasta en microsegundos (6 dígitos) de precisión."
stevepowell2000
1
¡Gracias, me has ayudado a hacer mi tarea antes! me encanta esta respuesta hermano! :) -habie
Habie Smart
10

Lo siguiente debería funcionar:

$now = date('Y-m-d');
$reservations = Reservation::where('reservation_from', '>=', $now)
                           ->where('reservation_from', '<=', $to)
                           ->get();
Pᴇʜ
fuente
8

Si desea verificar si la fecha actual existe entre dos fechas en db: => aquí la consulta obtendrá la lista de aplicaciones si la solicitud del empleado desde y hasta la fecha existe en la fecha de hoy.

$list=  (new LeaveApplication())
            ->whereDate('from','<=', $today)
            ->whereDate('to','>=', $today)
            ->get();
Juan
fuente
7

Prueba esto:

Dado que está obteniendo en función de un valor de una sola columna, puede simplificar su consulta de la misma manera:

$reservations = Reservation::whereBetween('reservation_from', array($from, $to))->get();

Recuperar basado en condición: laravel docs

Espero que esto haya ayudado.

ArtisanBay
fuente
6

Y he creado el alcance del modelo.

Más sobre osciloscopios:

Código:

   /**
     * Scope a query to only include the last n days records
     *
     * @param  \Illuminate\Database\Eloquent\Builder $query
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeWhereDateBetween($query,$fieldName,$fromDate,$todate)
    {
        return $query->whereDate($fieldName,'>=',$fromDate)->whereDate($fieldName,'<=',$todate);
    }

Y en el controlador, agregue la biblioteca de carbono al principio

use Carbon\Carbon;

O

use Illuminate\Support\Carbon;

Para obtener el registro de los últimos 10 días a partir de ahora

 $lastTenDaysRecord = ModelName::whereDateBetween('created_at',(new Carbon)->subDays(10)->toDateString(),(new Carbon)->now()->toDateString() )->get();

Para obtener el registro de los últimos 30 días a partir de ahora

 $lastTenDaysRecord = ModelName::whereDateBetween('created_at',(new Carbon)->subDays(30)->toDateString(),(new Carbon)->now()->toDateString() )->get();
Manojkiran.A
fuente
1
WhereDateBetween el segundo parámetro debe ser una matriz.
Mkey
Es solo un alcance del modelo, no es el método del constructor
Manojkiran.A
Oh sí, me perdí eso de alguna manera. Mi mal :)
Mkey
5

Si necesita saber cuándo un campo de fecha y hora debería ser así.

return $this->getModel()->whereBetween('created_at', [$dateStart." 00:00:00",$dateEnd." 23:59:59"])->get();
MIGUEL LOPEZ ARIZA
fuente
2
Hola, bienvenido a Stack Overflow. Cuando responda una pregunta que ya tiene muchas respuestas, asegúrese de agregar información adicional sobre por qué la respuesta que está brindando es sustantiva y no simplemente se hace eco de lo que ya ha sido examinado por el póster original. Esto es especialmente importante en respuestas de "solo código" como la que proporcionó.
chb
3

Sé que esta podría ser una pregunta antigua, pero me encontré en una situación en la que tuve que implementar esta función en una aplicación Laravel 5.7. A continuación se muestra lo que funcionó de mí.

 $articles = Articles::where("created_at",">", Carbon::now()->subMonths(3))->get();

También necesitará utilizar Carbon

use Carbon\Carbon;
Excelente Lawrence
fuente