php - 如何使用 laravel 8 获取 mysql 记录 created_at 时间戳之间的持续时间
问题描述
我想知道一个事件持续了多长时间,而不必为该事件添加完成时间。
为了演示,我创建了一个简单的练习:
事件表:
Schema::create('events', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
INSERT INTO `events` (`id`, `name`, `created_at`, `updated_at`) VALUES
(1, 'Event 1', '2021-08-19 10:41:16', '2021-08-19 10:41:16'),
(2, 'Event 2', '2021-08-19 11:11:25', '2021-08-19 11:11:25'),
(3, 'Event 3', '2021-08-19 11:25:21', '2021-08-19 11:25:21'),
(4, 'Event 4', '2021-08-19 11:35:28', '2021-08-19 11:35:28'),
(5, 'Event 5', '2021-08-19 11:45:38', '2021-08-19 11:45:38');
我目前正在从数据库中提取数据:
public function index()
{
return Event::get();
}
它返回以下内容:
{
id: 1,
name: "Event 1",
created_at: "2021-08-19T10:41:16.000000Z",
updated_at: "2021-08-19T10:41:16.000000Z"
},
{
id: 2,
name: "Event 2",
created_at: "2021-08-19T11:11:25.000000Z",
updated_at: "2021-08-19T11:11:25.000000Z"
},
{
id: 3,
name: "Event 3",
created_at: "2021-08-19T11:25:21.000000Z",
updated_at: "2021-08-19T11:25:21.000000Z"
},
{
id: 4,
name: "Event 4",
created_at: "2021-08-19T11:35:28.000000Z",
updated_at: "2021-08-19T11:35:28.000000Z"
},
{
id: 5,
name: "Event 5",
created_at: "2021-08-19T11:45:38.000000Z",
updated_at: "2021-08-19T11:45:38.000000Z"
}
我想取下一个事件的开始时间并将其用作结束时间来计算持续时间,如果没有下一个事件,则假定事件仍在运行,因此应使用当前时间计算持续时间。
假设我在 13:00 运行查询,我希望得到以下结果(持续时间以秒为单位计算):
[
{
id: 1,
name: "Event 1",
created_at: "2021-08-19T10:41:16.000000Z",
updated_at: "2021-08-19T10:41:16.000000Z",
duration: "1809"
},
{
id: 2,
name: "Event 2",
created_at: "2021-08-19T11:11:25.000000Z",
updated_at: "2021-08-19T11:11:25.000000Z",
duration: "836"
},
{
id: 3,
name: "Event 3",
created_at: "2021-08-19T11:25:21.000000Z",
updated_at: "2021-08-19T11:25:21.000000Z",
duration: "607"
},
{
id: 4,
name: "Event 4",
created_at: "2021-08-19T11:35:28.000000Z",
updated_at: "2021-08-19T11:35:28.000000Z",
duration: "610"
},
{
id: 5,
name: "Event 5",
created_at: "2021-08-19T11:45:38.000000Z",
updated_at: "2021-08-19T11:45:38.000000Z",
duration: "4462"
}
]
关于如何实现这一目标的任何建议?是否可以通过 eloquent 来实现,或者使用集合之类的东西并计算从数据库中提取数据后的持续时间会更好吗?
解决方案
您可以Collection::map()
结合使用Carbon::diffInMinutes()
(或者您想要区分):
public function index()
{
return Event::get()->map(function($event, $key) use($events) {
$event->duration = 0;
if ($key < $events->count() - 1) {
$event->duration = $events[$key + 1]->created_at->diffInMinutes($event->created_at);
}
return $event;
}));
}
如果您不喜欢在控制器中执行此操作,则可以直接在集合中执行此操作:
- 通过创建一个新集合
php artisan make:collection \\App\\Collections\\EventCollection
- 请执行下列操作:
<?php
namespace App\Collections;
use DatePeriod;
use Illuminate\Database\Eloquent\Collection;
class EventCollection extends Collection
{
public function withDuration()
{
return $this->map(function($event, $key) {
$event->duration = 0;
if ($key < $this->count() - 1) {
$event->duration = $this[$key + 1]->created_at->diffInMinutes($event->created_at);
}
return $event;
});
}
}
- 在您的
Event
模型中添加以下内容:
public function newCollection(array $models = [])
{
return new EventCollection($models);
}
- 像这样使用它:
public function index()
{
return Event::get()->withDuration();
}
推荐阅读
- c++ - CRT _crt_debugger_hook 第一个字节设置为 0xcc
- javascript - Blueprintjs 多选以编程方式设置值
- reactjs - 渲染两个嵌套对象
- visual-studio-code - VS 代码错误:在 mac os 中以代码 1 退出
- python - 使用循环在两个数组或列表中查找匹配值
- reactjs - 使用复选框使用 React 填充数组时,数组有重复的记录
- mysql - MYSQL 在两个相关表之间插入
- c - 用c编程语言将数据从文件读取到结构中
- docker - 当 Docker 中的 Jenkins 连接到 Docker Daemon 时,如何解决连接被拒绝的问题?
- android - 警告:链接器:警告:无法规范化“-rpath=/data/data/com.termux/files/usr/lib”