Current UTC time is: 2022-08-19 00:50
When I create a new record in my database I set created_at like:
'created_at' => Carbon::now()
But it stores Datetime like this -> 2022-08-18 20:50
Anyways, after couple of minutes I update this record and set updated_at like:
'updated_at' => Carbon::now()
And it stores it like this -> 2022-08-19 00:50 which is correct but not completely, because couple of minutes passed and it should be like 2022-08-19 00:53
Here is my migration file:
public function up() {
Schema::create('items', function (Blueprint $table) {
$table->id();
$table->timestamp('created_at');
$table->timestamp('updated_at')->nullable();
});
}
/config/app.php:
'timezone' => 'UTC',
My Item Model:
class Item extends Model {
use HasFactory;
public $timestamps = false;
}
Seriously, whats wrong with this datetime thing in laravel? Why it doesn't work like every other frameworks?
Note: I'm sick of laravels default $table->timestamps() it works even worse.
The answer listed here might be useful: How to update the updated_at column when the user logs in?
//instead of
'created_at' => Carbon::now()
// simply this:
$user->touch();
It was a problem related to database.
When you create a column this way $table->timestamp('created_at'), it creates a column in database with this structure:
|----------------------------------------------------------------------------|
| Name Type ... Null Default |
|----------------------------------------------------------------------------|
| created_at timestamp No current_timestamp() |
| |
|----------------------------------------------------------------------------|
If you pay attention to the Default column, you find out that this function uses the mysql server timestamp to set value for the created_at column and ignores your entry in laravel create() method.
To fix this problem you only have to set created_at to a nullable column like so:
$table->timestamp('created_at')->nullable();
Related
In the database I have columns: id, name, order, createdAt, updatedAt, createdBy, updateBy .
In controller : PostController.php
public function store(Request $request)
{
$req = Validator::make($request->all(), [
'name' => 'required',
'order' => 'required',
]);
if ($req->fails()) {
return response()->json(['error' => $req->errors()], 400);
}
$data = $request->all(); // name and order
Post::insert($item);
}
I want when I add data. Then createAt column and createBy column will be added. Instead of setting date('Y-m-d H:i:s) and $request->user()->id in controller, Then I want it to be placed in model, when i insert createAt and createBy columns are added. If it's update then I want the updatedAt and updatedBy columns to be added
You can add both createdAt and updatedAt in your migration file.
That will insert the current timestamp while inserting values into the table without adding them into the controller.
Please try like this while adding migration
Schema::create('table_name', function (Blueprint $table) {
$table->timestamp('createdAt');
$table->timestamp('updatedAt');
});
Instead of doing POST::insert($data); you could create/update a model more explicitly.
To add a new Post with only createdAt and createdBy you could do something like this:
$post = new Post;
$post->createdAt = $dateTime;
$post->createdBy = $userId;
$post->save();
Of course you can set any other attributes you are wanting to include before you save. And your updatedAt and updatedBy columns will have to be nullable in the database so that you don't get an error when you try to insert a record without including them.
Also as a note, Laravel has a feature that includes created_at and updated_at columns if you have: $table->timestamps(); included in your table's migration file. These fields will get automatically updated whenever a database entry is created/updated.
in your migration, you can just use the timestamps, it by default creates created_at and updated_at, and when you update an entry, Eloquent will update the value automatically for you, as for the created_by and updated_by, you can create them as well in migration, then setup an observer to set the values on create/update
ref: https://laravel.com/docs/8.x/eloquent#observers
This is a real stranger, when return the current time with Carbon, this is return ever time as UTC for me.
I do not understand why if I config as Europe/Madrid everything.
Example:
return Carbon::now()
The result is 2020-07-06 14:30:00
But is:
dd(Carbon::now())
The result is 2020-07-06 16:30:00
I not understand why.
My file app.php
'timezone' => 'Europe/Madrid',
And when load a model for example user
$user = User::find(1);
The created_at and updated_at return
2020-06-07 14:35:00
But in database the value saved is
2020-06-07 16:35:00
Carbon uses the default DateTime PHP object.
You can set custom timezone as :
$date = Carbon::createFromFormat('Y-m-d H:i:s', $tz, 'Europe/Madrid');
In the AppServiceProvider.php you can add the php functionality to alter the timestamp for the whole project :
public function boot()
{
Schema::defaultStringLength(191);
date_default_timezone_set('Europe/Madrid');
}
I want to add another created_at column on the database columns for reference.
I want to have a created_at and created_at1 at the same time.
This is what I have in my Model:
const CREATED_AT = 'created_at1';
protected $dates = [created_at, created_at1];
But I'm receiving this error: Field 'created_at' doesn't have a default value.
You do not need to add casting to the created_at since Laravel has already done it for you.
You need to add inside the string like
protected $dates = ['created_at1']
If you want to set the created_at1 when a new model is created, you can add Model Events.
Inside your model,
protected static function boot(){
parent::boot();
static::creating(function($model){
$model->created_at1 = Carbon::now();
});
}
Inside controller
$model = Model::create([
...
]);
Now it will set created_at and created_at1
For the insert, you have to manually save the value to the created_at1 because it will not reflect the model event.
Model::insert([
...
'created_at1' => Carbon::now()
]);
You might not be passing value to created_at column while inserting data. Please do check. If this is not the case please do provide more information on your problem.
I'm not able get the timestamps with dateformat 'U' working in lumen.
In migration:
$table->timestamps();
In Model:
protected $dateFormat = 'U';
protected $dates = [
'created_at',
'updated_at',
'deleted_at'
];
public function getDateFormat()
{
return 'U';
}
Insert row from controller:
$model = new ApiKey;
$model->random= rand();
$model->name = $name;
$model->scope = $scope;
$model->save();
It does insert the row in the database but with 0000-00-00 00:00:00 values for created_at and updated_at columns.
Also, while retrieving a model via toArray or toJson it thrown exception:
I want lumen to autoupdate the timestamps and retrive timestamps as unixtimestamp format i.e. number of seconds from 1st Jan 1970.
Also, $table->timestamps() didn't create deleted_at column. What do I need to do get this column created via laravel.
Is there any other option than $table->timestamp('deleted_at');?
I've found a solution bay changing timestamps columns to int. But I want the things to be done in laravel way.
Unix timestamps are integers, not compatible with SQL datetime/timestamp fields. If you want to use unix timestamps, use integer field types for storage.
The timestamps() method only creates created_at and updated_at, soft deletes are not enabled by default. This method should not be used if you want integer storage.
If you only want to change the output format when serializing data, use casting:
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'created_at' => 'datetime:U',
];
This is likely caused by the fact that Laravel/Lumen created the date/time columns as the type timestamp not int so you're trying to save wrong type of data in the field, causing the 0000-00-00 00:00:00.
This would also cause the carbon issue as you are trying to createFromFormat with the wrong format compared to the content.
You can use $table->integer('deleted_at'); in your migration to create a deleted_at column.
TL;DR:
Manually create your date time columns with $table->integer('updated_at').
<?php
namespace App\Traits;
use Illuminate\Support\Carbon;
trait sqlServerDateFormat
{
public function fromDateTime($value)
{
return Carbon::parse(parent::fromDateTime($value))->format('d-m-Y H:i:s');
}
}
I have a problem with updated_at, created_at fields in Laravel 5.
Here is my migration:
Schema::create('lots', function (Blueprint $table) {
$table->increments('id');
$table->integer('lot');
$table->integer('is_active');
$table->timestamps();
});
But when I insert some data into this table, updated_at and created_at fields are null. How make them auto-complete with current timestamps?
I insert data like this:
\DB::table('admin_lots')->insert([
'lot' => $request->cycle_lot,
'is_active' => '1',
]);
Thanks.
You have to use the create method instead of the insert method in Laravel.
The create method automatically adds timestamps for created_at and updated_at fields:
// GOOD:
User::create(array(
'name' => 'John'
));
On the contrary, the insert method bypasses Eloquent, (it uses the query builder) and does not update updated_at/created_at columns!
// BAD:
User::insert([
'name' => '[[ test name ]]',
]);
dd(
User::where(['name' => '[[ test name ]]'])->first()->create_date
);
You probably do not use Eloquent when inserting data, in this case you should add timestamps manually.
If you do not want to do this, but you still need filled timestamps, use this hack:
$table->timestamp('created_at')->default(\DB::raw('CURRENT_TIMESTAMP'));
$table->timestamp('updated_at')->default(\DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'));
Update
Based on your updated code, here's another solution:
\DB::table('admin_lots')->insert([
'lot' => $request->cycle_lot,
'is_active' => '1',
'created_at' = \Carbon\Carbon::now()->toDateTimeString(),
'updated_at' = \Carbon\Carbon::now()->toDateTimeString()
]);
Check if your model has this line.
public $timestamps = false;
If it has, delete it.
When you instert data directly, Laravel won't know about your timestamps.
You can either set the timestamps manually in the insert statement, or switch to using Eloquent models , which handle many things out of the box for you, including timestamps. It's also way easier to maintain than straight queries, where applicable.
Eloquent ORM
You need to use Laravel's awesome Eloquent feature to make timestamps written to the Database automatically...
As by seeing your example the code for eloquent will go something like this:
$lot_inputs = array(
'lot' => $request->cycle_lot,
'is_active' => 1
);
$new_lot = Lot::create($lot_inputs);
Please note that you should have the Model for the table = 'lots' (and it must extend Eloquent) so that you can easily use Eloquent methods and its properties...
It would be great if you use Eloquent ORM as much as possible so that if in future you want to change your DB technology then you won't need to specify the written eloquent queries again (e.g: the conversion of query to different DB languages is automatically done by Eloquent)
Thanks I hope this will help you to resolve your issue..!!