¿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.


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.


¿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();

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();

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();

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.


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();

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();

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;
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.