【发布时间】:2021-07-25 02:26:27
【问题描述】:
我正在尝试将 Laravel 项目中的一些数据按与标准有点不同的日期格式进行分组。我有一个数据库和一个查询,它根据用户想要查看的时间段获取用户网站的“正常运行时间检查”,然后我需要将其作为某种时间线显示给用户。
为了减少数据中的“噪音”(在给定时间段内可能没有足够的正常运行时间检查)我想在 3 小时内对我的所有结果进行分组一整天,所以我将拥有以下所有数据:
- 2021-05-02 03:00:00
- 2021-05-02 06:00:00
- 2021-05-02 09:00:00
等等,现在我按小时返回数据,但不知道如何修改它以达到预期的结果
// get the uptime checks for past X hours
$uptimeData = UptimeChecks::where('user_id', 1)
->where('monitor_id', 1)
->where('checked_at', '>=', '2021-05-02 13:00:00')
->where('checked_at', '<=', '2021-05-03 13:00:00')
->orderBy('checked_at', 'asc')
->select('event', 'checked_at')
->get();
$uptimeDataTimeline = $uptimeData->groupBy(function ($item, $key) {
$date = Carbon::parse($item->checked_at);
// group by hour, how can I get say every 3 hours worth of data?
return $date->format('Y-m-d H:00:00');
});
$uptimeDataTimeline = $uptimeDataTimeline->map(function ($checksInPeriod, $key) {
$down = 0;
$up = 0;
$total = 0;
$uptime = 0;
$fill = '#1fc777'; // green
// $checksInPeriod is all of the data for a given hour at the moment
// I need to group by a bigger period, say, every 3 hours
// add our events
foreach ($checksInPeriod as $key => $value) {
$total++;
if (strtolower($value['event']) == 'down') $down++;
if (strtolower($value['event']) == 'up') $up++;
}
// calculate uptime
$uptime = floatval(number_format(round($up / $total, 5) * 100, 2, '.', ','));
// fill colours
if ($uptime < 100) $fill = '#9deab8'; // lighter green
if ($uptime < 99) $fill = '#fbaa49'; // amber
if ($uptime < 98) $fill = '#e0465e'; // red
return [
'total_events' => $total,
'down_events' => $down,
'up_events' => $up,
'uptime' => $uptime,
'fill' => $fill
];
});
不确定如何修改返回格式的groupBy 函数,因为我的理解是不可能这样做?顺便说一句,我正在使用 Carbon。
更新
我一直在挖掘,并且遇到了CarbonInterval 功能,它允许我生成一些间隔,我已经尝试实现这个,我似乎得到了一个等间隔的时间段,但我的数据已经用完了并且不包含两个区间之间的所有数据(见附图)
$intervals = CarbonInterval::hours(2)->toPeriod($from, $to);
$uptimeDataTimeline = $uptimeData->groupBy(function ($item, $key) use ($intervals) {
$date = Carbon::parse($item->checked_at);
foreach ($intervals as $key => $interval) {
if ($date->hour == Carbon::parse($interval)->addHours(1)->hour) {
$actualHour1 = Carbon::parse($interval)->hour;
if (strlen($actualHour1) == 1) $actualHour1 = "0$actualHour1";
return $date->format("Y-m-d $actualHour1:00:00");
} else if ($date->hour == Carbon::parse($interval)->addHours(2)->hour) {
$actualHour2 = Carbon::parse($interval)->subHours(2)->hour;
if (strlen($actualHour2) == 1) $actualHour2 = "0$actualHour2";
return $date->format("Y-m-d $actualHour2:00:00");
}
}
return $date->format('Y-m-d H:00:00');
});
例如,我应该在 07 键中看到第 7 小时和第 8 小时的所有检查,但我看到的只是一小时(小时 11)的数据?
【问题讨论】:
-
所以你想有 8 个分区,每个分区 3 小时?
-
没错啊
标签: php sql laravel query-builder