Comment interroger entre deux dates en utilisant Laravel et Eloquent?


122

J'essaie de créer une page de rapport qui affiche les rapports d'une date spécifique à une date spécifique. Voici mon code actuel:

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

Ce que cela fait en SQL brut est select * from table where reservation_from = $now.

J'ai cette requête ici mais je ne sais pas comment la convertir en requête éloquente.

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

Comment puis-je convertir le code ci-dessus en requête éloquente? Merci d'avance.


quel est le format de la date reservation_from. vous pouvez utiliser les valeurs de carbone basées sur cela.
— Athi Krishnan

le format de la date est TIMESTAMP @AthiKrishnan
— wobsoriano

4
ce serait comme Reservation::where('reservation_from', '>=', Carbon::createFromDate(1975, 5, 21);) ->where('reservation_from', '<=', Carbon::createFromDate(2015, 5, 21);)->get(),;
— Athi Krishnan

Réponses:


247

La whereBetweenméthode vérifie que la valeur d'une colonne est comprise entre deux valeurs.

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

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

Dans certains cas, vous devez ajouter une plage de dates de manière dynamique. Basé sur le commentaire de @Anovative , vous pouvez faire ceci:

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

Si vous souhaitez ajouter plus de conditions, vous pouvez utiliser orWhereBetween. Si vous souhaitez exclure un intervalle de dates, vous pouvez utiliser whereNotBetween.

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

D' autres clauses utiles où: whereIn, whereNotIn, whereNull, whereNotNull, whereDate, whereMonth, whereDay, whereYear, whereTime, whereColumn, whereExists, whereRaw.

Laravel docs sur les clauses Where.


Comment cela serait-il géré si les $fromet $toétaient des dates dynamiques appartenant au modèle? Comme dans il y a un effective_atet des expires_atchamps et je veux interroger pour voir si l'élément actuel est dans cette plage. J'ai essayé each()avec un if qui utilise Carbon::now()->between( ... ), mais il renvoie toujours tous les résultats.
— Rockin4Life33

4
EDIT pour mon commentaire ci-dessus: négligé filter(), cela a fait l'affaire. MyModel::all()->where('column', 'value')->filter(function ($item) { if (Carbon::now->between($item->effective_at, $item->expires_at)) { return $item; } })->first();
— Rockin4Life33

1
@Anovative merci pour votre commentaire utile. Je mettrai à jour ma réponse en fonction de votre commentaire.
— Peter Kota

il ne donnera qu'à partir de l'enregistrement de la date.
— Muhammad

1
Il y a un problème avec la deuxième méthode. Il chargera tous les enregistrements de la base de données dans la mémoire et ensuite seulement il effectuera le filtrage.
— Jino Antony le

12

Une autre option si votre champ est datetimeau lieu de date( bien que cela fonctionne dans les deux cas ):

$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
techniquement, il n'aurait pas besoin d'être $ toDate. "23: 59.59.999"?
— stevepowell2000

@ stevepowell2000 Cela dépend de votre base de données, dans mon cas, nous stockons la date avec ce format 'AAAA-MM-JJ HH: MM: SS' dans un champ mysql datetime, sans précision en microsecondes. Informations connexes: dev.mysql.com/doc/refman/8.0/en/datetime.html
— tomloprod

Excellent point. Donc , si c'était un champ datetime ou timestamp nous peut aller tout le chemin à 23: 59: 59,999999 « Une valeur DATETIME ou TIMESTAMP peut inclure une partie de fractions de secondes en arrière jusqu'à microsecondes (6 chiffres) précision. »
— stevepowell2000

1
merci, vous m'avez aidé à faire ma tâche avant! aime cette réponse bro! :) -habie
— Habie Smart

10

Les éléments suivants devraient fonctionner:

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

8

Si vous voulez vérifier si la date actuelle existe entre deux dates dans db: => ici la requête obtiendra la liste des candidatures si la candidature de l'employé à partir de et à la date existe à la date d'aujourd'hui.

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

7

Essaye ça:

Étant donné que vous récupérez en fonction d'une seule valeur de colonne, vous pouvez simplifier votre requête de la même manière:

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

Récupérer en fonction de la condition: documentation laravel

J'espère que cela a aidé.


6

Et j'ai créé la portée du modèle

En savoir plus sur les portées:

Code:

   /**
     * 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);
    }

Et dans le contrôleur, ajoutez la bibliothèque Carbon en haut

use Carbon\Carbon;

OU

use Illuminate\Support\Carbon;

Pour obtenir le record des 10 derniers jours à partir de maintenant

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

Pour obtenir le record des 30 derniers jours à partir de maintenant

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

1
WhereDateBetween second paramètre doit être un tableau.
— Mkey

C'est juste une portée du modèle, ce n'est pas la méthode Builder
— Manojkiran.A

Oh ouais, j'ai raté ça d'une manière ou d'une autre. My bad :)
— Mkey

5

Si vous avez besoin de savoir quand un champ datetime doit être comme ça.

return $this->getModel()->whereBetween('created_at', [$dateStart." 00:00:00",$dateEnd." 23:59:59"])->get();

2
Bonjour, bienvenue dans Stack Overflow. Lorsque vous répondez à une question qui a déjà de nombreuses réponses, assurez-vous d'ajouter des informations supplémentaires sur les raisons pour lesquelles la réponse que vous fournissez est substantielle et ne fait pas simplement écho à ce qui a déjà été vérifié par l'affiche originale. Ceci est particulièrement important dans les réponses «code uniquement» telles que celle que vous avez fournie.
— chb

3

Je sais que c'est peut-être une vieille question, mais je me suis juste retrouvé dans une situation où je devais implémenter cette fonctionnalité dans une application Laravel 5.7. Voici ce qui a fonctionné de moi.

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

Vous devrez également utiliser du carbone

use Carbon\Carbon;
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.