如何将一天中的时间分成三个时段:上午,下午和晚上?

时间:2018-11-02 14:31:52

标签: php arrays time grouping bucket

我正在寻找从包含特定数字的数组中计算值的方法。基本上,我希望绘制出访问图表,并希望将其作为“早晨”,“下午”和“晚上”进行。因此,我想将诸如17:38的时间计算为17,然后对它们进行计数,以便我可以区分访问时间是上午,下午还是晚上。

$time_array = array("17:45","13:12","09:29","17:32","16:49","14:18");

$counts = array_count_values($time_array);
$morning_counts = $counts['09'] + $counts['10'] + $counts['11'];
$afternoon_counts = $counts['12'] + $counts['13'] + $counts['14'] + $counts['15'] + $counts['16'];
$evening_counts = $counts['17'] + $counts['18'] + $counts['19'] + $counts['20'] + $counts['21'] + $counts['22'] + $counts['23'];

样本数据的预期输出:

$morning_counts = 1
$afternoon_count = 3
$evening_counts = 2

7 个答案:

答案 0 :(得分:2)

您可以通过创建计数器变量来实现。然后,我们可以使用range()创建时间范围。然后获取时间字符串中:之前的值作为小时,然后将其与范围进行比较,如果在范围内,则将1加到计数器。

<?php
    $time_array = array("17:45","13:12","09:29","17:32","16:49","14:18");

    # create counter vars
    $mornCount = 0;
    $afternoonCount = 0;
    $eveCount = 0;

    # create range of times to compare against
    $mornRange = range(0, 11);
    $afternoonRange = range(12, 16);
    $eveRange = range(17, 23);

    foreach ($time_array as $time)
    {
        $compareTimeArr = explode(':', $time); # get first two chars of time
        $compareTime = $compareTimeArr[0];

        if (in_array($compareTime, $mornRange)) {
            $mornCount++;
        } elseif (in_array($compareTime, $afternoonRange)) {
            $afternoonCount++;
        } elseif (in_array($compareTime, $eveRange)) {
            $eveCount++;
        }
    }

    echo '<pre>'. print_r($mornCount,1) .'</pre>';
    echo '<pre>'. print_r($afternoonCount,1) .'</pre>';
    echo '<pre>'. print_r($eveCount,1) .'</pre>';

参考:

https://secure.php.net/manual/en/function.in-array.php

https://secure.php.net/manual/en/function.explode.php

https://secure.php.net/manual/en/function.range.php

答案 1 :(得分:1)

最简单的选择:

$time_array = array("17:45","13:12","09:29","17:32","16:49","14:18");
$times = [];
foreach ($time_array as $time) {
    $times[] = substr($time, 0, 2);
}

// Proceed with original code, but swap $time_array for $times

我认为这很丑陋。我通常建议使用DateTimes或DatePeriods而不是字符串。

答案 2 :(得分:1)

真的很简单,您可以在switch语句中完成

<?php
$time_array = array("17:45","13:12","09:29","17:32","16:49","14:18");

$morn = 0;
$after = 0;
$eve = 0;
$other = 0;
foreach ($time_array as $time) {
    $t = explode(':',$time)[0];
    switch ($t) {
        case '09':
        case '10':
        case '11':
        case '12':
            $morn++;
            break;

        case '13':
        case '14':
        case '15':
        case '16':
            $after++;
            break;

        case '17':
        case '18':
        case '19':
        case '20':
        case '21':
        case '22':
        case '23':
            $eve++;
            break;
        default:
            $other++;
    }
}
echo "Morning = $morn<br>";
echo "Afternoon = $after<br>";
echo "Evening= $eve<br>";
echo "Other = $other<br>";

答案 3 :(得分:1)

这应该只需几行即可完成:

$counts = array_reduce($time_array, function($counts, $time) {
  $hour = (int)substr($time, 0, 2);
  $moment = in_array($hour, range(9, 12)) ? 'morning' : (in_array($hour, range(13, 16)) ? 'afternoon' : 'evening');
  $counts[$moment]++;
  return $counts;
}, ['morning' => 0, 'afternoon' => 0, 'evening' => 0]);

Demo here

答案 4 :(得分:0)

这是另一种解决方案

<?php
$time_array = array("17:45","13:12","09:29","17:32","16:49","14:18");
$counts = countValues($time_array);
$morning_counts = $counts['09'] + $counts['10'] + $counts['11'] + $counts['12'];
$afternoon_counts = $counts['12'] + $counts['13'] + $counts['14'] + $counts['15'] + $counts['16'];
$evening_counts = $counts['17'] + $counts['18'] + $counts['19'] + $counts['20'] + $counts['21'] + $counts['22'] + $counts['23'] + $counts['24'];

var_dump($morning_counts, $afternoon_counts, $evening_counts);

function countValues($time_array) {
    $result = [];
    for ($i = 0; $i <= 23; $i++) {
        $key = ($i < 10) ? ('0' . $i) : (string) $i;
        $result[$key] = 0;
    }
    foreach ($time_array as $time) {
        $key = strstr($time, ':', true);
        $result[$key]++;
    }
    return $result;
}

答案 5 :(得分:0)

使用preg_match也可以得到次数。

$time_array = array("17:45","13:12","09:29","17:32","16:49","14:18");
function time_results($time_array){
    $result = array('morning_counts'=>0,'afternoon_counts'=>0,'evening_counts'=>0,'total'=>0);
    $result['total'] = count($time_array);
    foreach($time_array as $time){
        if(preg_match('/^(09|10|11|12)\:*/',$time)){
            $result['morning_counts'] += 1;
        }else if(preg_match('/^(13|14|15|16)\:*/',$time)){
            $result['afternoon_counts'] += 1;
        }else if(preg_match('/^(17|18|19|20|21|22|23|24)\:*/',$time)){
            $result['evening_counts'] += 1;
        }
    }
    return $result;
}

var_dump(time_results($time_array));
/*
result : array(4) { ["morning_counts"]=> int(1) ["afternoon_counts"]=> int(3) ["evening_counts"]=> int(2) ["total"]=> int(6) } 
*/

答案 6 :(得分:0)

这是我第一次在未调用usort()的代码段中使用“宇宙飞船运算符”或“三向比较运算符”。

它非常适合此任务,因为您要为时间值生成三个存储桶。

宇宙飞船运算符返回三个不同值之一:-101。比较两个字符串并确定左侧的值是less thanequal to还是greater than的右侧值是工作-然后返回我前一句话。

要设置此唯一的比较运算符(可从php7 +获得),我们需要对输入数字进行精简,以便可以正确地对其进行“存储”。

大多数人争先恐后explode()(而且常常不使用第3个参数(限制)来通知php所需要的元素不超过2个)。我不会,因为我不喜欢从字符串生成数组来捕获子字符串。因为时间值的格式是可预测的,所以最好的工具是substr($time, 0, 2),但是紧随其后的是strstr($time, ':', true),如果您想棘手"$time[0]$time[1]",也可以紧随其后。

我希望我的内嵌评论能够消除对我的简洁且功能强大的摘要的任何其他混淆。 (只需四行工作代码!)

代码:(Demo

$time_array = ["17:45", "13:12", "09:29", "17:32", "16:49", "14:18"];

$buckets = array_fill_keys([-1, 0, 1], 0);  // initialize buckets with 0 values

foreach ($time_array as $time) {
    ++$buckets[(int)sqrt(substr($time, 0, 2) - 8) <=> 2];
    //                                            ^^^^^-- 3-way comparison versus 2 
    //                                       ^^^--------- subtract 8 from the two-digit number
    //                   ^^^^^^^^^^^^^^^^^^^------------- extract first two digits from time string
    //             ^^^^^^-------------------------------- get squareroot value
    //         ^^^^--------------------------------- convert to integer (truncate decimals)
}

echo "Morning Count: {$buckets[-1]}\n";   // Hours: 00:00 to 11:59 ->12hrs (calculates as: 0, 1)
echo "Afternoon Count: {$buckets[0]}\n";  // Hours: 12:00 to 16:59 -> 5hrs (calculates as: 2)
echo "Evening Count: {$buckets[1]}";      // Hours: 17:00 to 23:59 -> 7hrs (calculates as: 3, 4)

输出:

Morning Count: 1
Afternoon Count: 3
Evening Count: 2

计算过程如何细分?

foreach (range(0, 23) as $t) {
    $calc = (float)sqrt($t - 8);
    echo "$t: " , (int)$calc , " ... [float value from sqrt was: $calc]\n";
}

从时间值023的细分:

//  |--------------------------------------------input time value
//  v  v-----------------------------------------final calculated value
//                                       vvv-----before converted to integer value
    0: 0 ... [float value from sqrt was: NAN]
    1: 0 ... [float value from sqrt was: NAN]
    2: 0 ... [float value from sqrt was: NAN]
    3: 0 ... [float value from sqrt was: NAN]
    4: 0 ... [float value from sqrt was: NAN]
    5: 0 ... [float value from sqrt was: NAN]
    6: 0 ... [float value from sqrt was: NAN]
    7: 0 ... [float value from sqrt was: NAN]
    8: 0 ... [float value from sqrt was: 0]
    9: 1 ... [float value from sqrt was: 1]
    10: 1 ... [float value from sqrt was: 1.4142135623731]
    11: 1 ... [float value from sqrt was: 1.7320508075689]
    12: 2 ... [float value from sqrt was: 2]
    13: 2 ... [float value from sqrt was: 2.2360679774998]
    14: 2 ... [float value from sqrt was: 2.4494897427832]
    15: 2 ... [float value from sqrt was: 2.6457513110646]
    16: 2 ... [float value from sqrt was: 2.8284271247462]
    17: 3 ... [float value from sqrt was: 3]
    18: 3 ... [float value from sqrt was: 3.1622776601684]
    19: 3 ... [float value from sqrt was: 3.3166247903554]
    20: 3 ... [float value from sqrt was: 3.4641016151378]
    21: 3 ... [float value from sqrt was: 3.605551275464]
    22: 3 ... [float value from sqrt was: 3.7416573867739]
    23: 3 ... [float value from sqrt was: 3.8729833462074]