将时间数组合并为压缩的时间范围(如果连续)

问题描述 投票:0回答:2

我有一个时间列表,需要将其分组为简化的连续块。

$array = [
    [
        "08:30",
        "09:00",
        "09:30",
        "10:00",
        "14:30",
        "15:00",
        "15:30",
        "16:00",
        "16:30"
    ],
    [
        "13:30",
        "14:00",
        "14:30",
        "18:00",
        "18:30",
        "19:00"
    ]
];

我正在尝试将它们转换为这种格式:

[
    [
        ['08:30', '10:00'],
        ['14:30', '16:30']
    ],
    [
        ['13:30', '14:30'],
        ['18:00', '19:00']
    ]
]

我需要这个,因为 jQuery 插件正在使用(日安排选择器)。

如果时间差为:30 分钟或更短,则将时间压缩为一组。

这是我尝试过的:

$prepared = '';
foreach ($serialized as $day => $hours) {
    $prepared_hours = array();
    foreach ($hours as $hour) {
        $prepared_hours[] = "['" . $hour . "']"; 
    }
    $prepared .= "'{$day}' : [". implode(',', $prepared_hours) . "],\n";
}

但结果是:

'0' : [['08:30'],['09:00'],['09:30'],['10:00'],['14:30'],['15:00']‌​,['15:30'],['16:00']‌​,['16:30']], 
'1' : [['13:30'],['14:00'],['14:30'],['18:00'],['18:30'],['19:00']
php time range grouping strtotime
2个回答
2
投票

循环时,跟踪先前迭代的时间并将其与当前迭代的时间进行比较。

当开始一个新组时,销毁之前创建的引用(如果还存在),然后声明一个新引用并将其推入结果数组中。

在处理连续时间时,将当前时间专门推入参考变量的第二个元素。

代码:(演示

function compactTimes(
    array $times,
    string $format = 'H:i',
    string $separation = "30 minutes"
): array {
    $result = [];
    $prev = null;
    foreach ($times as $time) {
        if (!$prev || $time !== date("H:i", strtotime("+$separation $prev"))) {
            unset($ref);
            $ref = [$time, $time];
            $result[] =& $ref;
        } else {
            $ref[1] = $time;
        }
        $prev = $time;
    }
    return $result;
}

var_export(
    array_map('compactTimes', $array)
);

-1
投票

也许这可以让你开始:

$start = new \DateTime('9:00');
$end = new \DateTime('14:00');
$period = new \DatePeriod($start,new \DateInterval('PT30M'),$end);

foreach ($period as $date) {
    print $date->format('H:i') . '<br>';
}
© www.soinside.com 2019 - 2024. All rights reserved.