I'm creating a schedule function where i validate a date field in a table against the current date, if the date is past then i want to update the second column with '3224407' . the field type fecha_vigencia is date.
my schedule function is :
protected function schedule(Schedule $schedule)
{
$schedule->call(function(){
foreach(Equipo::all() as $equipo){
$fecha_vigencia= Carbon::parse($equipo->fecha_vigencia);
if($fecha_vigencia->isPast())
{
DB::table('equipo')->update(['telefono_contacto' => '3224407']);
}
}
}
now my database records before running schedule:run :
image
most of the date fields in the fecha_vigencia column are in the future "2017-08-15",
as displayed on the image above, when i compare against the current date-> "2017-07-31" ,using $fecha_vigencia->isPast(), all fields on the Telephone column are updated. only should update 1 field with date 2017-07-10 instead.
what's wrong with the function?
thanks in advance
You most likely wanted something like this
$equipo->telefono_contacto = '3224407';
$equipo->save();
instead of
DB::table('equipo')->update(['telefono_contacto' => '3224407']);
Right now you're effectively updating the whole table each time $fecha_vigencia->isPast().
Related
I have an input field that will provide me the 24 hour format time like 16:30, 18:22, 13:50 etc. So how to set migration column for this.
I read already documentation but not did not understand.
As #M Khalid Junaid has suggested, you should define a mutator for your attribute on your model to modify the value of a normal timestamp.
So firstly, you need to create the column in the migration:
$table->timestamp('your_column_name');
Then, you can create your mutator on your model just like any method. We are going to use Carbon to play around with the format. Keep in mind that the name of the mutator needs to be the camelCase of your column name:
protected function yourColumnName(): Attribute
{
return new Attribute(
get: fn ($value) => Carbon::parse($value)->format('H:i'),
);
}
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.
I have some timestamp records on the DB that have trailing milliseconds at the timestamp and some not have. How to allowing that trailing data (millisecond) in carbon? Is this possible?
Here's the sample of my data
I can't always change the data manually because there are some other services using the same database and sometimes storing timestamp with trailing milliseconds.
As you are using Postgres, your timestamp probably has TIME WITH TIMEZONE
Example: "2018-04-19 07:01:19.929554".
In Such case have to add a date Mutator to your Model.
In your Model add this field for date mutator:
protected $dateFormat = 'Y-m-d H:i:sO';
Alternate Solution:
As you have a mix of timestamps with and without milliseconds I suggest you try this solution using Laravel field mutators:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* Parse the created at field which can optionally have a millisecond data.
*
* #param string $created_at
* #return Carbon::Object
*/
public function getCreatedAtAttribute($created_at)
{
// Try to remove substring after last dot(.), removes milliseconds
$temp = explode('.', $created_at);
// If created_at had milliseconds the array count would be 2
if(count($temp) == 2) {
unset($temp[count($temp) - 1]); // remove the millisecond part
} else {
$temp = [$created_at]; // created_at didnt have milliseconds set it back to original
}
return Carbon::parse(implode('.', $temp))->format('Y-m-d H:i:s')
}
}
I have observed in Laravel, storing datetime in database ignores
millisecond field, probably depends on version and db server type.
Also Laravel has whereData() and whereTime() query builders but we
need something like whereDateTimeTz() in all cases.
I recommend storing datetime as unix timestamps in database.
From user timezone convert to GMT and save it to db as millis-timestamp
Carbon::parse('date', 'user_timezone')->setTimezone('GMT')->getPreciseTimestamp(3);
While displaying just convert the db timestamp (GMT) back to user timezone including DST status.
Laravel 7 provides better date parsing by falling back to Carbon::parse if the recevied timestamp from the database doesn't match the expected $dateFormat.
PR: https://github.com/laravel/framework/pull/30628
I'm trying to make a simple scope for a model which has "end_time" as a dateTimeTz() column in Laravel 5.8. I'm using:
public function scopeActive($query)
{
return $query->whereNull('end_time')->orWhere('end_time', '>', Carbon::now());
}
But this is only comparing the date element of the end_time column, and giving me everything ending strictly after today, when I want anything ending later on today as well.
What is the correct way of going about this?
I have table training_schedules
id (int, pk)
course_reference (varchar)
start_date (date)
end_date (date)
year_id (int, fk)
and years
id (int, pk)
value (int)
Now I want to create a search query using the TrainingSchedule eloquent model. I want to search by course_reference (using like) and start_date(optional) based on month (dropdownlist on form) and year (optional)
optional conditions means I will check if the form data for the fields are filled on the search form. If not I will just skip those conditions.
How can I achieve this using Eloquent ORM? if not, how to do it on another way?
You can create a query over multiple calls. So something like the following will probably do what you're looking for:
// start query off with a non-optional query
$results = TrainingSchedule::whereLike('course_reference', Input::get('course_reference'));
// only if we were sent a start date, add it to the query
if (Input::has('start_date')) {
$results->whereStartDate(Input::get('start_date'));
}
// if we were sent a month, ensure start date's month is the same month as the one passed in
if (Input::has('month')) {
$results->where(DB::raw('MONTH(`start_date`)'), Input::get('month'));
}
// only if we were sent a year, add it to the query
if (Input::has('year')) {
$results->whereHas('year', function ($query) { $query->whereValue(Input::get('year')); });
}
// get actual results from db
$results = $results->get();