Как разделить время дня на 3 ведра: утром, днем ​​и вечером?

Я рассчитываю подсчитать значения из массива, который содержит определенное число. По сути, я планирую построить график посещений и хочу сделать это «утром», «днем» и «вечером». Поэтому я хочу посчитать время, например, 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

0

Решение

Вы можете сделать это, создав переменные счетчика. Затем мы можем создать диапазоны временных интервалов, используя 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

2

Другие решения

Самый простой вариант:

$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 вместо строк.

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>";
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]);

Демо здесь

1

Здесь приходит другое решение

<?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;
}
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) }
*/
0

Это первый раз, когда я использовал «оператор космического корабля» или «оператор трехстороннего сравнения» в фрагменте, который не вызывал usort(),

Он идеально подходит для этой задачи, потому что вы хотите сгенерировать три сегмента для ваших значений времени.

Оператор космического корабля возвращает одно из трех разных значений: -1, 0, а также 1, Его задача — сравнить две строки и решить, является ли значение слева less than, equal to, или же greater than значение справа — затем возвращает соответствующее числовое значение, упомянутое в моем предыдущем предложении.

Чтобы настроить этот уникальный оператор сравнения (доступный из php7 +), нам нужно сварить входные числа, чтобы они могли быть правильно «объединены».

Большинство людей спешат explode() (и слишком часто не используйте 3-й параметр (limit), чтобы сообщить php, что требуется не более 2 элементов). Я этого не делаю, потому что мне не нравится генерировать массив из строки только для захвата подстроки. Поскольку значения времени предсказуемо отформатированы, лучшим инструментом для этой задачи будет substr($time, 0, 2), но внимательно следит за strstr($time, ':', true) и если вы хотите быть хитрым "$time[0]$time[1]",

Я надеюсь, что мои встроенные комментарии прояснят любые другие заблуждения относительно моего краткого и мощного фрагмента. (Всего 4 строки рабочего кода!)

Код: (демонстрация)

$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";
}

Разбивка по временным значениям 0 в 23:

//  |--------------------------------------------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]
0