How to insert date format YY-MM into database? - laravel

I have been trying to get the the Year and Month from the user and insert them into the database.
i am using input type month so that the user can send only the Year and the Month.
<input type="month" name="date_from"/>
<input type="month" name="date_to"/>
and this is my model
function setDateFromAttribute($value)
{
$this->attributes['date_from'] = \Carbon\Carbon::createDateFromFormat('Y-m', $value);
}
function setDateToAttribute($value)
{
$this->attributes['date_to'] = \Carbon\Carbon::createDateToFormat('Y-m', $value);
}
protected $fillable = [
'date_from',
'date_to',
];
and data is saved as 0000.00.00
the data type in my database for these two inputs is
timestamp
i do not know what i am doing wrong here. please help

I don't see createDateFromFormat as a valid Carbon method in the documentation https://carbon.nesbot.com/docs/
Likewise, there does not appear to be any createDateToFormat method.
Carbon::createFromFormat() returns a Carbon object, not a string or equivalent MySQL timestamp, so, assuming you change your code to be:
$this->attributes['date_from'] = \Carbon\Carbon::createFromFormat('Y-m', $value)->toDateTimeString();
It should provide the results you are looking for.
References:
Converting a carbon date to mysql timestamp.

#Ted Stresen-Reuter
Sorry for the late reply couldn't find a solution that works within the model. tried your method which i have tried before with minor changes.
thanks a lot for trying to help me.. i found a method to complete this inside the controller which i will not recommend, but this was the best i was able to find which works and i was on a tight schedule.
'date_from' => isset($date_from[$key]) ? date('Y-m-d h:i:s', strtotime($date_from[$key])) : '',
'date_to' => isset($date_to[$key]) ? date('Y-m-d h:i:s', strtotime($date_to[$key])) : '',
the type timestamp accepts at least dates in full formats. as i know how i pass the data from blade to the controller i was able to add a date method and within it a strttotime method to convert my YY-MM into YY-MM-DD and the date that is inserted by default will be 01.

Related

Laravel eloquent compare datetime with query builder

I'd like to compare datetime values (with date AND time). First I tried this, but it does not work, as it only compares the date, not the time:
$events = $events->whereDate('end', '>=', $input['after']);
I thought that a simple where would help, but it does not:
$events = $events->where('end', '>=', $input['after']);
The reason for that is, that my input value is 2022-10-10T00:00:00 and the database read gives 2022-10-10 00:00:00 (the T in the middle was added in the input).
I'd like to stick to the isoformat (using the T), however inside the database that format gets casted to a value without T it seems. The reason for that might be the cast in the model: 'end' => 'datetime',
What would be the best way to solve this issue and compare datetime objects (and how)?
Change the model cast
Cast the input
What would be the best way to solve this issue and compare datetime objects
The best way is still to convert the input with the data type format of the date and time column
You can use : $dateConvert = date('Y-m-d H:i:s', strtotime($input['after']));
But I suggest you use carbon library :
$dateConvert = \Carbon\Carbon::parse($input['after'])->format('Y-m-d H:i:s');
And :
$events = $events->where('end', '>=', $dateConvert );

Laravel - different formats for date/time query

I am learning Laravel and I have some small problem on controllers - when I use DB, the query returns date time without timezone but if I use model, the query returns full datetime.
public function test($switch)
{
//return "YYYY-MM-DDThh:mm:ss.000000Z"
if ($switch) return Position::select('id','created_at')->orderBy('id')->get();
// return "YYYY-MM-DD hh:mm:ss"
return DB::table('positions')->select('id','created_at')->orderBy('id')->get();
}
Why? What I need to dof I want "YYYY-MM-DDThh:mm:ss.000000Z" on both cases?
Thanks for solution.
thanks for advice
You should use the DB::raw
The following statement will convert the datetime value created_at from +00:00 timezone to +10:00 timezone.
You can try this
return DB::table('positions')->select(DB::raw('id',CONVERT_TZ('created_at','+00:00','+10:00'))->orderBy('id')->get();
you can set your timezone that you wants to convert it
They are the same data, probably just different classes of date and you can always format your date. Laravel utilizes Carbon date library which is excellent and should be used primarily.
If you try to print out your date class with get_class() for Eloquent Position created_at, you probably got Carbon and DB::table('positions') created_at, you probably got DateTime and that's why the value looks different (but you still got the same date).
If you want to convert your DateTime to Carbon, you can do
$newDate = new \Carbon\Carbon($position->created_at)
Thanks Anurat,
I realized this fact shortly after sending the previous question.
... but there is another 'issue' - both times are my local time - time in "YYYY-MM-DDThh:mm:ss.000000Z" is not UTC time as I expected.
I changed my function:
public function test($switch = false)
{
$data = Position::selectRaw('id, created_at, UNIX_TIMESTAMP(created_at) unix')->orderBy('id')->get();
foreach ($data as $d) {
$conv = new \DateTime($d->created_at);
$d->conv = intval($conv->format('U'));
$d->diff = $d->conv - $d->unix;
}
return $data;
}
... and result is
0
id 1
created_at "2021-03-18T12:36:59.000000Z"
unix 1616067419
conv 1616071019
diff 3600
As you see, the difference is 1 hour (as my timezone offset). Where is a problem?
Thanks.

Manual function inside query?

Is there any way to put a manual function inside a query in Laravel.
I've timestamp saved in string in DB. I want to convert timestamp from one timezone to another. All the timestamp is inserted in one time zone, and depending upon my user I fetch the timestamp and convert it into their timezone.
what I want to achieve is something like this..
$query = BlogCategory::select('merchant_id', userTime(added_at))
->where('site_id', $site_id)
->get();
userTime() function takes two parameter, the timestamp and the timezone and converts the timsestamp to time of the user.
I want to use userTime() function before fetching the data. I dont want to fetch the data first and then do foreach and so on.
I know I might be absolutely absurd but is there anything of this sort in Laravel?
Well you can achieved that using collection map
$query = BlogCategory::select('merchant_id', 'added_at')
->where('site_id', $site_id)
->get();
$dateAdded = $query->map(function ($data) {
// try this if error $data['merchant_id']
return array(
'merchant_id' => $data->merchant_id,
'added_at' => $this->userTime($data->added_at)
);
})
dd($dateAdded);
Read Collection documentation here: https://laravel.com/docs/5.8/collections
You should use the selectRaw statement and let your DB do this logic for you if you don't want to loop over the result set.
For example if your underlying database is MySQL you can use the CONVERT_TIMEZONE function and do something like this.
BlogCategory::selectRaw('merchant_id, CONVERT_TZ(added_at, "GMT", "MET") as added_at')
->where('site_id', $site_id)
->get();

Laravel: Check if time + 4 hours has passed

I store in my database a date format like this:
2017-02-22 16:55:40
I added it to my database like this:
Carbon::now();
I need to check if 4 hours passed since this date.
How I can do this? I couldn't figure out how I can convert this format into Carbon or timestamp.
If you are using Laravel and the date is a Carbon instance from a Model you have access to the whole Carbon API.
You can use the Difference API of Carbon for this specific purpose.
echo $model->thedate->diffInHours($now, false);
If your model does not threat the date as a carbon instance you can cast it by adding the date to the dates array of the current model like so
protected $dates = [
'field_name',
];
Check out Date casting for more information
Update with an explicit example
$user = User::first();
// This will return the difference in hours
$user->created_at->diffInHours(Carbon\Carbon::now(), false);
You can convert it to a Carbon object with:
Carbon::parse('2017-02-22 16:55:40');

Laravel - convert input date format before save

I'm trying to convert date input to the proper mysql format.
My start_date field is formatted MM dd, yyyy.
In my controller store function I'm grabbing all the users input including start_date and saving.
$userProfileData->save();
What I thought I could do is us Carbon to convert the start_date before save like this.
$userProfileData->start_date->toDateString();
I get a Call to a member function toDateString() on a non-object error.
I was able to convert the date format by adding this to my users controller store function.
$userProfileData->start_date = date('Y-m-d', strtotime($userProfileData->start_date));
you get non-object error because start_date is not the object with method toDateString()
what you can do is use setStartDateAttribute() method in your model which will be invoked every time to get the start_date attribute value and in this method you can modify value so model will use the updated value for operation like edit or update it can be as follow
public function setStartDateAttribute($value) {
$this->attributes['start_date'] = date('Y-m-d', strtotime($value) );
}
the following method will used by your model when it needs to get the value of start_date attribute this method must be written in the model

Resources