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.