在 laravel 中将时间戳保存到数据库的正确方法?
Right way to save timestamps to database in laravel?
作为带有 vuejs 和 axios 前端的标准 laravel 应用程序的一部分,当我尝试将 ISO8601 值保存到 action_at 字段时,出现异常。
class Thing extends Model {
protected $table = 'things';
// timestamp columns in postgres
protected $dates = ['action_at', 'created_at', 'updated_at'];
protected $fillable = ['action_at'];
}
class ThingController extends Controller {
public function store(Request $request) {
$data = $request->validate([
'action_at' => 'nullable',
]);
// throws \Carbon\Exceptions\InvalidFormatException(code: 0): Unexpected data found.
$thing = Thing::create($data);
}
}
我的主要要求是数据库准确保存客户认为保存的时间。如果另一个进程决定对“action_at”列执行操作,则不应因为时区而延迟几个小时。
我可以更改 laravel 代码,或者我可以选择不同的时间格式发送到 Laravel。 laravel 解决此问题的正确方法是什么?
默认的 created_at
和 updated_at
应该可以正常工作。
- 您应该始终将
config/app.php
中的时区设置为 UTC
- 在
users
table 中添加时区列或您喜欢的任何一个
- 在前端执行 time-offsets 或 api 响应
这是在后端进行时间偏移的示例代码
$foo = new Foo;
$foo->created_at->setTimezone('America/Los_Angeles');
或使用 momentjs 的前端
moment(1650037709).utcOffset(60).format('YYYY-MM-DD HH:mm')
or using moment-timezone
moment(1650037709).tz('America/Los_Angeles').format('YYYY-MM-DD HH:mm')
class Thing extends Model {
protected $table = 'things';
// timestamp columns in postgres
protected $dates = ['action_at', 'created_at', 'updated_at'];
protected $fillable = ['action_at'];
}
class ThingController extends Controller {
public function store(Request $request) {
$data = $request->validate([
'action_at' => 'nullable',
]);
// convert ISO8601 value, if not null
if ($data['action_at'] ?? null && is_string($data['action_at'])) {
// note that if the user passes something not in IS08601
// it is possible that Carbon will accept it
// but it might not be what the user expected.
$action_at = \Carbon\Carbon::parse($data['action_at'])
// default value from config files: 'UTC'
->setTimezone(config('app.timezone'));
// Postgres timestamp column format
$data['action_at'] = $action_at->format('Y-m-d H:i:s');
}
$thing = Thing::create($data);
}
}
其他提示:如果您想将它与 protected $dates
一起使用,请不要使用 postgres timestamptz 列,laravel 不知道如何像 postgres [=20] 那样将其提供给 carbon =] 额外的时区数据。
请参阅 carbon 文档以了解您可以使用 \Carbon\Carbon 的 $action_at
实例执行的其他操作,例如确保日期不会太晚或太早。 https://carbon.nesbot.com/docs/
作为带有 vuejs 和 axios 前端的标准 laravel 应用程序的一部分,当我尝试将 ISO8601 值保存到 action_at 字段时,出现异常。
class Thing extends Model {
protected $table = 'things';
// timestamp columns in postgres
protected $dates = ['action_at', 'created_at', 'updated_at'];
protected $fillable = ['action_at'];
}
class ThingController extends Controller {
public function store(Request $request) {
$data = $request->validate([
'action_at' => 'nullable',
]);
// throws \Carbon\Exceptions\InvalidFormatException(code: 0): Unexpected data found.
$thing = Thing::create($data);
}
}
我的主要要求是数据库准确保存客户认为保存的时间。如果另一个进程决定对“action_at”列执行操作,则不应因为时区而延迟几个小时。
我可以更改 laravel 代码,或者我可以选择不同的时间格式发送到 Laravel。 laravel 解决此问题的正确方法是什么?
默认的 created_at
和 updated_at
应该可以正常工作。
- 您应该始终将
config/app.php
中的时区设置为UTC
- 在
users
table 中添加时区列或您喜欢的任何一个
- 在前端执行 time-offsets 或 api 响应
这是在后端进行时间偏移的示例代码
$foo = new Foo;
$foo->created_at->setTimezone('America/Los_Angeles');
或使用 momentjs 的前端
moment(1650037709).utcOffset(60).format('YYYY-MM-DD HH:mm')
or using moment-timezone
moment(1650037709).tz('America/Los_Angeles').format('YYYY-MM-DD HH:mm')
class Thing extends Model {
protected $table = 'things';
// timestamp columns in postgres
protected $dates = ['action_at', 'created_at', 'updated_at'];
protected $fillable = ['action_at'];
}
class ThingController extends Controller {
public function store(Request $request) {
$data = $request->validate([
'action_at' => 'nullable',
]);
// convert ISO8601 value, if not null
if ($data['action_at'] ?? null && is_string($data['action_at'])) {
// note that if the user passes something not in IS08601
// it is possible that Carbon will accept it
// but it might not be what the user expected.
$action_at = \Carbon\Carbon::parse($data['action_at'])
// default value from config files: 'UTC'
->setTimezone(config('app.timezone'));
// Postgres timestamp column format
$data['action_at'] = $action_at->format('Y-m-d H:i:s');
}
$thing = Thing::create($data);
}
}
其他提示:如果您想将它与 protected $dates
一起使用,请不要使用 postgres timestamptz 列,laravel 不知道如何像 postgres [=20] 那样将其提供给 carbon =] 额外的时区数据。
请参阅 carbon 文档以了解您可以使用 \Carbon\Carbon 的 $action_at
实例执行的其他操作,例如确保日期不会太晚或太早。 https://carbon.nesbot.com/docs/