【问题标题】:How to get duration between mysql records created_at timestamp using laravel 8如何使用 laravel 8 获取 mysql 记录 created_at 时间戳之间的持续时间
【发布时间】:2021-08-19 12:31:44
【问题描述】:

我想知道一个活动持续了多长时间,而不必为该活动添加结束时间。

为了演示我创建了一个简单的练习:

事件表:

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 来实现,或者使用集合之类的东西并计算从数据库中提取数据后的持续时间会更好吗?

【问题讨论】:

标签: php mysql laravel eloquent


【解决方案1】:

您可以将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;
    }));
}

如果您不喜欢在控制器中执行此操作,您可以直接在集合中执行此操作:

  1. 通过php artisan make:collection \\App\\Collections\\EventCollection 创建一个新集合
  2. 执行以下操作:
<?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;
        });
    }
}
  1. 在您的 Event 模型中添加以下内容:
public function newCollection(array $models = [])
{   
    return new EventCollection($models);
}
  1. 像这样使用它:
public function index()
{   
    return Event::get()->withDuration();
}

【讨论】:

  • 感谢您的回答,我想这就是我所需要的。目前收到一个错误,说 $events 未定义.. 将重新查找如何使用集合并再试一次
  • 不客气。我修好了它。现在应该可以工作了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-14
  • 2015-03-30
  • 1970-01-01
  • 1970-01-01
  • 2022-11-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多