I have an input file with call start datetime and call end datetime separated by ‘|’. I am trying to read in the file row-by-row and calculate the maximum number of overlapping/concurrent calls. I’ve been trying, but I can’t seem to get correct.
Example input file:
2023-01-19 11:18:17|2023-01-19 11:21:59
2023-01-19 11:18:30|2023-01-19 11:19:06
2023-01-19 11:18:58|2023-01-19 11:20:04
2023-01-19 11:20:56|2023-01-19 11:21:56
2023-01-19 11:21:18|2023-01-19 11:24:42
2023-01-19 11:21:26|2023-01-19 11:22:02
2023-01-19 11:21:56|2023-01-19 11:22:38
2023-01-19 11:22:47|2023-01-19 11:26:59
2023-01-19 11:23:40|2023-01-19 11:24:58
2023-01-19 11:25:10|2023-01-19 11:25:46
2023-01-19 11:25:51|2023-01-19 11:27:57
2023-01-19 11:26:01|2023-01-19 11:26:37
2023-01-19 11:26:01|2023-01-19 11:27:37
2023-01-19 11:26:19|2023-01-19 11:26:55
2023-01-19 11:27:23|2023-01-19 11:28:59
2023-01-19 11:27:35|2023-01-19 11:27:47
2023-01-19 11:28:26|2023-01-19 11:28:38
My code currently looks like this (I apologize, I was having a hard time with the text editor here so it looks a little disjointed and missing a "{" after the function name…):
function readcsv($filename) {
$handle = fopen($filename, "r");
if ($handle) {
$data = [];
$max = 0;
$calls = 0;
$datetime = "";
while (($line = fgetcsv($handle, null, "|")) !== false) {
if (!isset($data["previousendmax"])) {
$data["previousendmax"] = $line[1];
}
if (!isset($data["previousendmin"])) {
$data["previousendmin"] = $line[0];
}
$startdate = $line[0];
$enddate = $line[1];
if (
$startdate >= $data["previousendmin"] &&
$startdate <= $data["previousendmax"]
) {
$calls++;
}
if (
$enddate > $data["previousendmax"] ||
$startdate > $data["previousendmax"]
) {
$calls--;
}
if ($startdate > $data["previousendmin"]) {
$data["previousendmin"] = $enddate;
}
if ($enddate > $data["previousendmax"]) {
$data["previousendmax"] = $enddate;
}
if ($calls > $max) {
$max = $calls;
$data["previousend"] = $line[1];
$datetime = $line[0];
}
echo "Current Calls: " . $calls . "n";
echo "Max Calls: " . $max . "n";
print_r($data["previousendmin"]);
echo "n";
print_r($data["previousendmax"]);
echo "n";
}
fclose($handle);
}
print_r($max);
The current output is:
Current Calls: 1
Max Calls: 1
2023-01-19 11:18:17
2023-01-19 11:21:59
Current Calls: 2
Max Calls: 2
2023-01-19 11:19:06
2023-01-19 11:21:59
Current Calls: 2
Max Calls: 2
2023-01-19 11:19:06
2023-01-19 11:21:59
Current Calls: 3
Max Calls: 3
2023-01-19 11:21:56
2023-01-19 11:21:59
Current Calls: 2
Max Calls: 3
2023-01-19 11:21:56
2023-01-19 11:24:42
Current Calls: 2
Max Calls: 3
2023-01-19 11:21:56
2023-01-19 11:24:42
Current Calls: 3
Max Calls: 3
2023-01-19 11:21:56
2023-01-19 11:24:42
Current Calls: 3
Max Calls: 3
2023-01-19 11:26:59
2023-01-19 11:26:59
Current Calls: 3
Max Calls: 3
2023-01-19 11:26:59
2023-01-19 11:26:59
Current Calls: 3
Max Calls: 3
2023-01-19 11:26:59
2023-01-19 11:26:59
Current Calls: 2
Max Calls: 3
2023-01-19 11:26:59
2023-01-19 11:27:57
Current Calls: 2
Max Calls: 3
2023-01-19 11:26:59
2023-01-19 11:27:57
Current Calls: 2
Max Calls: 3
2023-01-19 11:26:59
2023-01-19 11:27:57
Current Calls: 2
Max Calls: 3
2023-01-19 11:26:59
2023-01-19 11:27:57
Current Calls: 2
Max Calls: 3
2023-01-19 11:28:59
2023-01-19 11:28:59
Current Calls: 2
Max Calls: 3
2023-01-19 11:28:59
2023-01-19 11:28:59
Current Calls: 2
Max Calls: 3
2023-01-19 11:28:59
2023-01-19 11:28:59
3
Of course, at the end of the list, it should show zero calls so I know it’s not working as expected. If I were to review the first 6 lines list manually, I would expect the following of concurrent calls:
1
2
3
2
3
4
Where I’m struggling is how to account for calls that ended before the next row started… but happened to be a couple rows above the row I’m currently evaluating. For example, row 4, it’s starting at 11:20:56 which means that by the time that call starts, the calls on both rows 2 and 3 have ended. Can anyone point me in the right direction? Thanks!
I’ve tried to construct a rolling "window" of time and then calculate the number of calls going on at the same time within that window, but this method isn’t working as expected (certainly because I’m a novice and doing it wrong).
2
Answers
I spoke to a colleague and he suggested the following: When a call starts, it's +1 When a call ends, it's -1 So break up the rows. Using the first 6 rows as an example:
Then, sort by the date/time and calculate them:
Pretty easy when you approach it like this!
If I understand the question correctly, the problem is to find the periods between changes, where a change is a phone call starting or a phone call ending.
For simpler testing lets start with an array instead of reading in a CSV file (which is not related to the question):
Output: