strtotime() expects parameter 1 to be string, array given in laravel - php

i want to make time slot between the start time and end time and show the disponibility of the user but i get this error : strtotime() expects parameter 1 to be string, array given
this is the controller :
$model=doc::findOrFail($ID);
$ReturnArray = array ();// Define output
$StartTime = strtotime ($model->Lun_mat_de) ; //Get Timestamp
$EndTime = strtotime ($model->Lun_mat_a); //Get Timestamp
$duration = '60';
$AddMins = $duration * 15;
//Run loop
while ($StartTime <= $EndTime) {
$ReturnArray[] = date ("G:i", $StartTime);
$StartTime += $AddMins; //Endtime check
}
return view ('/rendezvous',['go'=> $model],['jaja'=>$ReturnArray] );
this is the view :
<div class="div1" ></div>
#foreach($jaja as $ja)
<button class="btn btn-info"> {{$ja}} </button> </br>
#endforeach
this is the model :
protected $table = 'doctor' ;
protected $casts = [
'Lun_mat_de' =>'array',
'Lun_apres_a' =>'array',
];

The value $model->Lun_mat_de is an array variable type rather than a string, as expected.
From Comments:
what does print_r($model->Lun_mat_de) show?
["8:30","12h30"]
Right, that is an array, which of these values do you want to be turned into a time value?
Lun_mat_de' and 'Lun_mat_a'
No, You have told me that $model->Lun_mat_de gives you an array of two values, you need to choose which of these two values you want the PHP function strtotime to work on. 8:30 or 12h30?
oh sorry yes 8:30
Ok,
So to get the strtotime function to work on 8:30 you would put:
$StartTime = strtotime ($model->Lun_mat_de[0]); //8:30
To get the strtotime function to work on the other value, the 12h30 then you would reference the other array value:
$StartTime = strtotime ($model->Lun_mat_de[1]); //12h30
(I assume here the array is integer keyed)
Recommended Reading:
Please read the PHP Manual entry on array, string types as well as the function strtotime.
Also you should actually probably be using the DateTime function going forward.

You defined in you model casts Lun_mat_de => array so $model->Lun_mat_de always returns you an array. so strtotime ($model->Lun_mat_de) will crash. fix the casts field

Related

Can not extract year with DateTime::createFromFormat

I'm trying to extract the year of a input date like
$start = $request->input('start');
$refYear = DateTime::createFromFormat("Y-m-d H:i:s", $start)->format("Y");
But I'm having the error Call to a member function format() on boolean and i saw another answers but nothing result so far.
Where start is defined as a input in my page
<input id="start" type="text" name="start" class="date-type"
placeholder="dd-mm-aaaa"><i class="fi-calendar" style="top: 2px;"></i>
In my table the startDate column is a date time like '2017-10-26 00:00:00.000' and refyear is a int (2017).
According to the documentation DateTime::createFromFormat:
Returns a new DateTime instance or FALSE on failure.
This is why you call it on a boolean, because the value is false.
Your format seems to be correct, that means createFromFormat can not handle your $start . Your input does not match your format, make sure it matches.
The following for instance works:
echo (DateTime::createFromFormat("Y-m-d H:i:s", "2019-01-01 12:30:30"))->format("Y"); // result: 2019
#jeprubio from the comments is right btw. - add the milliseconds to match your given format:
echo DateTime::createFromFormat("Y-m-d H:i:s.u", "2017-10-26 00:00:00.000")->format("Y"); // 2017
You can try to use Carbon instead:
$refYear = Carbon::createFromFormat("Y-m-d H:i:s", $start)->format("Y");
But also your format is wrong you are missing .u based on your example of the date field. You should use this:
$refYear = Carbon::createFromFormat("Y-m-d H:i:s.u", $start)->format("Y");

Carbon in Laravel -- Call to a member function addDay() on integer

I'm trying to build a scheduler in which an incremental day addition and subtraction method is required.
Here, I am simply trying to add a day to this variable (which is displayed to the user elsewhere) each time this function is executed via a button I set up that routes to a certain location. But, I keep getting this error
Call to a member function addDay() on integer
whenever I try to execute this. I am new to using the Carbon interface and looked through the documents, which led me to try parsing the function (worked when I had the same error with a string) but to no avail obviously. Any help is appreciated and/or a possible explanation of how this error is working really.
function addDay(){
$day = (int) Carbon::now()->format('j');
$day = $day->addDay();
}
Thanks in advance. If there is a better way to do this (adding days incrementally with the button/link), I would love to hear it. My logic seems flawed after working on the application the entire day.
You're casting the Carbon date object into an integer by using the (int) in the first $day variable. Therefor when you're trying to access the function addDay() it's failing, because $day is no longer a Carbon object but an integer.
$day = Carbon::now();
$day = $day->addDay()->format('j');
This should work, and if you need to cast it to an integer for some reason, then do it like this.
$day = Carbon::now();
$day = (int) $day->addDay()->format('j');
This way you cast the integer after you've added the day.
There is also a much cleaner approach to this syntax, which uses method chaining like so
$day = (int) Carbon::now()->addDay()->format('j');
As #Classified said but a cleaner approach would be to work with Carbon object first and then apply format on that.
Like this:
$dateObj = Carbon::now()->addDay();
$day = (int) $dateObj->format('j');
Cleaner approach and better readability.
What is the desired returned value ?
$day = Carbon::now()->addDay();
return $day->dayOfWeek; //day of the week, 03/08/18 (now) returns 6 (INT)
return $day->format('j'); //day of the month, 03/08/18 (now) returns "4" (STRING)
return $day->day; //day of the month, 03/08/18 (now) returns 4 (INT)
return $day //Carbon object (at now() + 24h) that you can manipulate
You have to addDay to Carbon instance not to the integer (the day) :
$dt = Carbon::create(2012, 1, 31, 0); // 2012-01-31 00:00:00
echo $dt->addDay(); // 2012-03-04 00:00:00

Laravel Carbon Date Difference between two dates

I have a field in my DB which has a time stamp using moment js. The result is like so.
["2018-02-11 11:30:17","2018-02-11 11:20:17","2018-02-11 11:10:17"]
But when i return created_at colum from db the array is given like so:
[{"date":"2018-02-11 11:40:17.000000","timezone_type":3,"timezone":"Asia\/Karachi"},{"date":"2018-02-11 11:40:31.000000","timezone_type":3,"timezone":"Asia\/Karachi"},{"date":"2018-02-11 11:40:40.000000","timezone_type":3,"timezone":"Asia\/Karachi"}]
So how can i take two column dates in a format where carbon can understand? I want the "starttime" column to compare with "created_at". Is this achievable? Here is my code so far:
$cleanStart = Clean::pluck('starttime')->toArray();
$cleanFinish = Clean::pluck('created_at')->toArray();
$from = Carbon::parse($cleanStart);
$to = Carbon::parse($cleanFinish);
$diff_in_hours = $to->diffInHours($from);
return $diff_in_hours;
But it gives me an error:
Type error: DateTime::__construct() expects parameter 1 to be string, array given
Also how can i give the array to carbon.
So finally here is the thing i tried:
$cleanCollection = Clean::get(['starttime','created_at']);
foreach($cleanCollection as $cleanObj){
$startTime = Carbon::parse($cleanObj->starttime);
$diff = $cleanObj->created_at->diffInseconds($startTime);
}
echo $diff;
But when ever i refresh the page, the value changes in seconds. and if another record is added, it adds up again.
Pluck will give you an array of all of the start times from your result set which is why you're passing an array into parse. You're actually getting all of the start times and all of the created ats then trying to compare all to all, effectively.
You either need to get a single result,
Like
$clean = Clean::first();
$from = Carbon::parse($clean->starttime);
$to = Carbon::parse($clean->created_at);
$diff_in_hours = $to->diffInHours($from);
Or if you wanted it for each row you'd have to iterate over them and do much the same
Clean::all()->each(function ($clean) {
$from = Carbon::parse($clean->starttime);
$to = Carbon::parse($clean->created_at);
$diff_in_hours = $to->diffInHours($from); // for this row
});
The other thing you could do is put an accessor on your Clean model to help you out with this
public function getDiffInHoursAttribute()
{
$from = Carbon::parse($this->starttime);
$to = Carbon::parse($this->created_at);
return $to->diffInHours($from);
}
Then
echo Clean::first()->diffInHours;
Or
foreach(Clean::all() as $clean) {
echo $clean->diffInHours;
}
Also, if you add the following to your model, Eloquent will automatically parse the strings into Carbon objects so you can skip the need for Carbon::parse() in your code
/**
* The attributes that should be mutated to dates.
*
* #var array
*/
protected $dates = [
'starttime'
];
Try adding protected $dates to your Clean model, like this:
/**
* The attributes that should be mutated to dates.
*
* #var array
*/
protected $dates = [
'created_at',
'updated_at'
];
As you can read from the comments inside the code, put all of the columns that should be converted to dates inside, this will help you achieve date manipulations easier.
EDIT 1:
$start = new Carbon($cleanStart['date'], $cleanStart['timezone']);
$finish = new Carbon($cleanFinish['date'], $cleanFinish['timezone']);
Then you can compare like this:
var_dump($start->eq($finish)); //Is start date same as finish date
var_dump($start->ne($finish)); //Is start date not same as finish date
var_dump($start->gt($finish)); //Is start date greater than finish date
var_dump($start->gte($finish)); //Is start date greater than or equal to finish date
var_dump($start->lt($finish)); //Is start date less than finish date
var_dump($start->lte($finish)); //Is start date less than or equal to finish date
EDIT 2:
In order for the code underneath to work, you must initialize $start and $finish dates as in EDIT 1
$ago = $start->diffForHumans($finish, true); //2 days OR 3 weeks OR 1 hour

converting H:i:s to minutes only but array_map() giving errors

I am trying to convert a long datatype data to time in which I am successful.
In each session time array I have values like ["1276999","787878","677267"]. I passed this array in the array_map function and converted to time which is working.
Now within the the convert_time function I am calling another function, using array_map which will convert each time (i.e 1:40:00 to 100 minutes) but the issue is my 2nd array map function which is giving me error that array_map needs 2nd parameter to be an array...
$each_session_time = array();
for ($i=0; $i<sizeof($array_in_time_str) ; $i++) {
$each_session_time[$i]=$array_out_time_str[$i]-$array_in_time_str[$i];
}
//session time in hours
array_map("convert_to_time", $each_session_time);
function convert_to_time($each_session) {
# code...
$each_sess_time=array();
$each_sess_time=date("H:i:s",$each_session);
array_map("get_minutes",$each_sess_time);
return $each_sess_time;
}
function get_minutes($session_time) {
// algorithm to convert each session time to minutes)
}
You need to move out the array_map("get_minutes",$each_session_time); from the convert_to_time function.
example:
<?php
$each_session_time=["1276999","787878","677267"];
//session time in hours
$times = array_map("convert_to_time", $each_session_time);
$minutes = array_map("get_minutes",$times);
function convert_to_time($each_session)
{
# code...
$each_sess_time=array();
$each_sess_time=date("H:i:s",$each_session);
return $each_sess_time;
}
function get_minutes($session_time)
{
//algo to convert each session time to minutes)
}
print_r($minutes);
It seems you are starting with valid timestamps - seconds passed since January 1, 1970 - so to get the difference between two values in minutes, you just have to subtract one from the other and multiply it by 60.
If you want more control over your data, for example to format it differently later on, I would recommend using DateInterval objects instead of the difference between two timestamps and strings that you are using now. Note that the difference between two timestamps is not a valid timestamp itself so you cannot use date() to format it.
considering you are working with strings like "XX:YY:ZZ" you can try
$split = explode(":",$session_time); $minutes = $split[1];
to get the "i" part of the string.
You could also use a dateTime object (http://php.net/manual/en/class.datetime.php) by doing new DateTime($each_session); in the first loop and using DateTime::format("H:i:s") and DateTime::format("i") on that object depending on what data you need

PHP shortcut to find smallest number / date

I have a situation whereby a series of 15 dates have been created, currently in UNIX timestamps.
Another variable <?php $dateidate = date(strtotime('+20 days')); ?>
The objective is to find the smallest of the 15 other dates that is greater > than $dateidate and display in the format of 'd-m-Y'
Once we've done that is there a way to get the second smallest of the 15 other dates that is greater > than $dateidate and display in the format of 'd-m-Y'.
So, you have 15 dates which are UNIX timestamps. Useful.
Ok, here's what you can do to do it easily:
$datearray = array(timestamp1,timestamp2,etc.) // an array of timestamps
$dateidate = time() + 1728000; //current time + 20 days worth of seconds (20 * 24 * 60 * 60)
foreach($datearray as $key => $date)
{
if($date < $dateidate)
{
unset $datearray[$key]; //Remove timestamp from original array if less than $dateidate
}
}
$earliestdate = min($datearray);
//min returns the least of the values in the array, opposite of max, which you could use to find the latest date in the array
$date = date('d-m-Y',$earliestdate);
strtotime generates a timestamp.
instead of this:
<?php $dateidate = date(strtotime('+20 days')); ?>
do this:
<?php $dateidate = strtotime('+20 days'); ?>
Put all timestamps into an array with special keys so you can distinguish which one is your pivot.
Sort that array and do what you need to do with the sorted array.
This solution filters the $dates array which stores the timestamps using an anonymous function, so in the $shorterOnes array you will have all the timestamps that are bigger than $dateidate.
Then the array is sorted, the first one will be smallest and so on.
$dateidate=strtotime('+20 days');
$dates=array(/*timestamps*/);
$shorterOnes=array_filter($dates, function ($v) use ($dateidate) {
return $v>$dateidate;
});
sort($shorterOnes);
echo date('d-m-Y', $shorterOnes[0]);
echo date('d-m-Y', $shorterOnes[1]);
Anonymous functions only work from PHP 5.3. Lower than that, you need to use create_function().

Categories