kendrick's avatar

Carbon::createFromFormat issue

I am trying to check on a whereDoesntHave method on a $query, based on a $date:

$date = Carbon\Carbon::createFromFormat('Y-m-d H:i', $request->date . $request->time);
$requestedTime = $date;

dd($requestedTime);
results in:

Carbon @1577702400 {#588 ▼
  date: 2019-12-30 10:40:00.0 UTC (+00:00) 
}

// the time format does not equal H:i right?

Then I am checking on:

$query
   ->where('date', $requestedTime->format('Y-m-d'));
$query
   ->where('time', '>=', $requestedTime->format('H:i'))
   ->where('time', '<=', $requestedTime->format('H:i')); // but I guess it fails here with the format

Any suggestions?

0 likes
12 replies
gazd1977's avatar

What do $request->date and $request->time look like?

kendrick's avatar
$date = $request->date;

dd($date);

"2019-12-30"

$time = $request->time;

dd($time);

"10:40"
gazd1977's avatar

Agree the Carbon instance looks odd, but if you output the items in your query they do seem to be giving you the data in the way you want.

$requestedTime->format('Y-m-d')
outputs "2019-12-30"


$requestedTime->format('H:i');
outputs "10:40"

What are you trying to find in the second query? You appear to be searching for a time that is both equal to or less than and greater than or equal to in the same query. Isn't that the same as time = to something?

$query
   ->where('time', '>=', $requestedTime->format('H:i'))
   ->where('time', '<=', $requestedTime->format('H:i'));

is the same as

$query
   ->where('time', '>=', "10:40")
   ->where('time', '<=', "10:40");

which is the same as

$query
   ->where('time', "10:40");

How are you storing dates/times in your database?

kendrick's avatar

Trying to implement a simple meeting logic, and check if the $requestedTime exists for this $doctor, if not create the meeting.

$this->validate($request, [
        'date' => 'max:50|required', 
        'time' => 'date_format:H:i|max:140|required',  
]);


$date = Carbon\Carbon::createFromFormat('Y-m-d H:i', $request->date . $request->time);
$requestedTime = $date;
$requestedDoctorId = $request->get('doctor_id'); 
// (Doctor.php, Method: meetings(return $this->hasMany(Meeting::class, 'doctor_id');))

$doctor = Doctor::where('id', $requestedDoctorId)
      ->whereDoesntHave('meetings', function ($query) use ($requestedTime) {
        $query
        ->where('date', $requestedTime->format('Y-m-d'));
        $query
        ->where('time', '>=', $requestedTime->format('H:i'))
        ->where('time', '<=', $requestedTime->format('H:i'));
 });

if ($doctor instanceof Doctor) {
    
// This doctor is available
// create meeting 
}else{

// doctor is not available
// e.g. return redirect back with info not available

}

But somehow, even if there is no meeting on the $requestedTime it redirects back with the info not available.

gazd1977's avatar

I always just use eloquent for querying the database, so im not overly familiar with query builder etc, but are you pulling in Illuminate\Database\Eloquent\Builder?

I also wonder if the two $query items should be chained into a single $query? Don't you also need a retrieval method on the end of the query (->get(), ->first())? In the docs the example uses ->get().

$doctor = Doctor::where('id', $requestedDoctorId)
      ->whereDoesntHave('meetings', function ($query) use ($requestedTime) {
        $query
        ->where('date', $requestedTime->format('Y-m-d'))
        ->where('time', '=', $requestedTime->format('H:i'));
 }->get());

What column types are you using to store the dates/times?

I see in the docs that there are some additinoal where clauses that might be of assistance as well i.e. whereDate / whereTime

kendrick's avatar
What column types are you using to store the dates/times?

$table->date('date');
$table->time('time');

If I add get() like

 })->get();

it just returns the Staff Model. As I am checking whereDoesntHave, I thought that I don't need to get the collection, and only check the instance, and else redirect back.

But it just won't work.

gazd1977's avatar

You might be right re: checking whether its an instance of - ive never seen/tried that, but i guess end result would be the same.

What does the meetings table look like? Presumably you are storing the doctor_id in that table?

kendrick's avatar

Yes, storing the doctor_id, as an unsignedInteger within the meetings_table.

gazd1977's avatar

If you query that table directly - can you get the result you want (i.e. prove the subquery - via query builder is valid)?

Once that can be established you could then rework into whereDoesntHave method again?

Snapey's avatar

I don't think you understand what createFromFormat does.

It creates a Carbon instance at a specific time. That time includes seconds, milliseconds and the timezone

The response you see in the first question is exactly what I would expect

kendrick's avatar

Ok, but even if I use $request within my $query:

->whereDoesntHave('meetings', function ($query) use ($request) {
        $query
        ->where('date', $request->date)  
        ->where('time', '=',  $request->time);

and then check on the Doctor instance, it will redirect back with the info not available, even though there are no meetings for the chosen date/ time.

Where could it fail?

Snapey's avatar
Snapey
Best Answer
Level 122

Why even bother with Carbon?


$doctor = Doctor::where('id', $request->doctor_id)
      ->whereDoesntHave('meetings', function ($query) use ($request) {
        $query
        ->where('date', $request->date)
        ->where('time', $request->time)
     })->first();

Please or to participate in this conversation.