How to sum time periods between dates,and get the average - php

I have an array,each element have a start_date and end_date.
I want to sum all the time periods between the two dates and divide them by 3 to get the average time period.
The Array
Array
(
[0] => Array
(
[start_date] => "2014-01-30 09:27:02"
[end_date] => "2014-01-30 16:29:38"
)
[1] => Array
(
[start_date] => "2014-01-28 09:27:02"
[end_date] => "2014-01-30 16:29:38"
)
[2] => Array
(
[start_date] => "2014-01-30 09:05:02"
[end_date] => "2014-01-30 12:12:38"
)
)
I need some thing like this:
$total=0;
foreach($array as $ar)
{
$created_dt=strtotime($ar[$start_date]);
$done_dt=strtotime($ar[$end_date]);
$runing_time= $created_dt - $done_dt - 2*3600;
$runing_time= date('H:i',$runing_time);
$total+=$runing_time;
}
$runing_time=$total/3;
what is a good way to do this?
thanks :)

You are making a fundamental mistake in trying to treat a time period as a date/time, you cannot use date() and its related functions for time periods.
The way to find the average of time periods is to sum the number of seconds and then divide that by the number of periods. The following function does this:-
function averageTime(array $times){
$total = 0;
foreach($times as $time){
$total += (new \DateTime($time['end_date']))->getTimestamp() - (new \DateTime($time['start_date']))->getTimestamp();
}
$avSeconds = $total/count($times);
$hours = floor($avSeconds/3600);
$avSeconds -= $hours * 3600;
$minutes = floor($avSeconds/60);
$avSeconds -= $minutes * 60;
$seconds = floor($avSeconds);
return "{$hours}h {$minutes}m {$seconds}s";
}
Plugging your example array into it:-
$times= array(
0 => Array(
'start_date' => "2014-01-30 09:27:02",
'end_date' => "2014-01-30 16:29:38",
),
1 => Array(
'start_date' => "2014-01-28 09:27:02",
'end_date' => "2014-01-30 16:29:38",
),
2 => Array(
'start_date' => "2014-01-30 09:05:02",
'end_date' => "2014-01-30 12:12:38",
),
);
echo "Average time = " . averageTime($times);
Output:-
Average time = 21h 44m 16s
Ref DateTime manual.

As shown at this answer it's ultra simple. :) (i have slightly modified it)
$now = time(); // or your date as well
$your_date = strtotime("2010-01-01");
$datediff = $now - $your_date;
$numberOfDays = floor($datediff/(60*60*24));
Now you just have to put it in foreach and sum in $numberOfDays in another variable.
And please remember to check if first date is lower than second date

Technically you are already correct.
But it order to have the given script to run propely you may have edit it to
$total=0;
foreach($array as $ar)
{
$created_dt=strtotime($ar['start_date']);
$done_dt=strtotime($ar['end_date']);
$runing_time= $created_dt - $done_dt - 2*3600;
$runing_time= date('H.i',$runing_time);
$total+=$runing_time;
}
$runing_time=$total/3;
so I only changed 3 thing.
first your $start_date and $end_date was an variable that was not existing.
and second if you want the average instead of : put . so it can be read as a double.
and if you want the variable $total to be the real value i would do this instead.
$runing_time= date('H',$runing_time).'.'.date('i',$runing_time)/60*100;

Related

Count months from a date to December then count months from January the following year to December that same year, then from January to end date

I have a start_date of 1/10/2018, and an end_date of 1/8/2020, the difference between the two dates in months is 22, that is 1 year 10 months, now, I want to create tables that terminate at the end of each year as follows:
table 1
column_heading will be "1/10/2018 - 31/12/2018"
and the row will be "2 months"
table 2
column_heading will be "1/1/2019 - 31/12/2019"
and the row will be "12 months"
table 3
column_heading will be "1/1/2020 - 1/8/2020"
and the row will be "8 months"
I would like to loop something, maybe the difference between the dates to create the number of tables necessary, if the two dates exist within the same year it will only create 1 table, or 2 if it enters the next year, I am using laravel and carbon to manipulate the dates.
Thank you in anticipation of your help.
Something like this
Here's one way. Note that I had to convert the format of your dates to YYYY-mm-dd in order to use PHP date functions. In the end you'll get an array and it's easy for you to transform the final dates into the format you desire. You can test it here: https://www.tehplayground.com/lvuTdWl91TeItEQC
The code:
<?php
// example code
$s = "1/10/2018";
$e = "1/08/2020";
// reassemble so we can use the date functions YYYY-mm-dd
$s = implode("-", array_reverse(explode("/", $s)) );
$e = implode("-", array_reverse(explode("/", $e)) );
// get the parts separated
$start = explode("-",$s);
$end = explode("-",$e) ;
$iterations = ((intVal($end[0]) - intVal($start[0])) * 12) - (intVal($start[1]) - intVal($end[1])) ;
$sets=[$start[0] => array("start" => $s, "end" => "", "months" => 0)];
$curdstart= $curd = $s;
$curyear = date("Y", strtotime($s));
for($x=1; $x<=$iterations; $x++) {
$curdend = date("Y-m-d", strtotime($curd . " +{$x} months"));
$curyear = date("Y", strtotime($curdend));
if (!isset($sets[$curyear])) {
$sets[$curyear]= array("start" => $curdend, "end" => "", "months" => 0);
}
$sets[$curyear]['months']++;
$sets[$curyear]['end'] = date("Y-m-", strtotime($curdend)) . "31";
}
die(print_r($sets,1));
$mctr = 0 ;
The output:
Array
(
[2018] => Array
(
[start] => 2018-10-1
[end] => 2018-12-31
[months] => 2
)
[2019] => Array
(
[start] => 2019-01-01
[end] => 2019-12-31
[months] => 12
)
[2020] => Array
(
[start] => 2020-01-01
[end] => 2020-08-31
[months] => 8
)
)

Stuck at date-format in seconds

first of all, I'm sorry for my english. I'm from germany.
Now my Problem:
I have a multiple array with some dates in it. I had to filter the first and the last date for every IP because I need the difference of both dates to know how much time the User on my website.
I did that and got all I need. Here is a part of my code output:
$ip_with_dates:
Array
(
[0] => Array
(
[ip] => 72.xx.xx.xx
[first_date] => 2015-10-12 00:10:15
[last_date] => 2015-10-12 01:10:51
)
[1] => Array
(
[ip] => 85.xx.xx.xx
[first_date] => 2015-10-12 00:10:19
[last_date] => 2015-10-12 01:10:56
)
I tried to get the time between those two dates with:
$visit_lenght = [];
foreach($ip_with_date as $key => $val){
$date1 = new DateTime($val['first_date']);
$date2 = new DateTime($val['last_date']);
$interval = $date1->diff($date2)->format('%h %m %s');
$visit_lenght[] = $interval;
}
what gives me this output:
Array
(
[0] => 1 36
[1] => 1 37
[2] => 0 3
[3] => 0 9
)
well but this isn't good to work with. I need the time in seconds not in H:m:s
but I really don't now how. This is a part of my project where I'm really fighting with. Maybe someone of you could help me with this.
I'm working with laravel. Normal PHP would make it too but if someone knows a solution in laravel, it would be nice as well!
thanks for any help!
To get time diff in seconds you need to convert your datetime objects to timestamps:
$visit_lenght = [];
foreach($ip_with_date as $key => $val){
$date1 = new DateTime($val['first_date']);
$date2 = new DateTime($val['last_date']);
$interval = $date1->getTimestamp() - $date2->getTimestamp()
$visit_lenght[] = $interval;
}
You may get timestamps of two dates and count the difference.
something like (in php).
$date1t = $date1->getTimestamp();
$date2t = $date2->getTimestamp();
$diff = $date2t - $date1t;
http://php.net/manual/en/datetime.gettimestamp.php
Try this way (general/basic way)
$visit_lenght = [];
foreach($ip_with_date as $key => $val){
$date1 = strtotime($val['first_date']);
$date2 = strtotime($val['last_date']);
//$interval = $date1->diff($date2)->format('%h %m %s');
$interval = $date2 - $date1;
$visit_lenght[] = $interval;
}
you can make this:
->format('Y-m-d H:i:s')
With DateTime() class of PHP, it is super simple to find difference between time. Here is an exmple:
<?php
$ip = "xxxx-xxx-xxx";
$t1 = DateTime::createFromFormat('Y-m-d H:i:s', '2015-10-12 00:10:15');
$t2 = DateTime::createFromFormat('Y-m-d H:i:s', '2015-10-12 01:10:51');
echo "User from IP {$ip} spent " . $t1->diff($t2)->format("%h hours, %i minutes and %s seconds");
?>

DateTime "diff"

I think Time object is just a mess. I really never learn how they works.
I have an array with data: 09:00-09:20 and 12:30-13:00.
Now i like to calculate the time between 09:00-09:20.
So i break up the array:
$break_1_dur = $usr_breaks['skift_rast1'];
//returns: 09:00-09:20
I break up the string:
$break_1_start = substr($break_1_dur,0,5);
//returns: 09:00
$break_1_ends = substr($break_1_dur,6,5);
//returns: 09:20
And now i'll use DateTime diff to calculate the time:
$break_1_dur = $break_1_start->diff($break_1_ends);
I have tried to make strings to "DateTime" with:
$break_1_start = new DateTime();
How can i in a easy way calculate this?
This should work for you:
Here I first split your array into the following structure with array_map():
Array
(
[skift_rast1] => Array
(
[start] => 09:00
[end] => 09:20
)
[skift_rast2] => Array
(
[start] => 12:30
[end] => 13:00
)
)
The I loop through all $times and calculate the difference with creating DateTime objects and get the difference via diff():
<?php
$usr_breaks = ["skift_rast1" => "09:00-09:20", "skift_rast2" => "12:30-13:00"];
$times = array_map(function($v){
return array_combine(["start", "end"], explode("-", $v));
}, $usr_breaks);
//print differences
foreach($times as $time) {
$timeOne = new DateTime($time["start"]);
$timeTwo = new DateTime($time["end"]);
$interval = $timeOne->diff($timeTwo);
echo sprintf("%d hours %d minutes<br>", $interval->h , $interval->i);
}
?>
output:
0 hours 20 minutes
0 hours 30 minutes

What is the best way to subtract "after-hours" time from a date range to get an accurate "active" time?

I have 2 parallel arrays that contain mysql timestamps. The first array contains "Start" times, and the second array contains "Stop" times.
Example
Starts
Array ( [0] => 2014-12-05 12:21:29 [1] => 2014-12-10 07:14:17 [2] => 2014-12-10 12:43:47 [3] => 2014-12-12 07:39:28 [4] => 2014-12-12 08:13:30 )
Stops
Array ( [0] => 2014-12-08 08:08:37 [1] => 2014-12-10 10:13:37 [2] => 2014-12-12 07:18:53 [3] => 2014-12-12 08:10:39 [4] => 2014-12-12 08:27:26 )
I need to add the total times based off of all the starts and stops in each array, but I also need to subtract all the time that was "after-hours". This is for reporting purposes.
So let's say that any time after 4pm(16:00) and before 6am(06:00) needs to be removed from the total active time that will be reported.
I already have it subtracting weekend time, but I also need it to remove the "after-hours" time if it occurs after-hours on a weekday. The checks for weekday/weekend aren't a problem, but figuring out how to check if the time range contains hours that were after business hours is what is stumping me.
Here is how I am subtracting the weekend time:
function getWeekendSeconds($starts, $stops){
$count = 0;
$secondsToSubtract = 0;
$secondsInDay = 86400;
if(count($starts) > count($stops)){
while(count($starts) != count($stops)){
array_pop($starts);
}
}
foreach($starts as $start){
$stop = $stops[$count];
$startTime = strtotime($start);
$stopTime = strtotime($stop);
while($startTime < $stopTime){
$dayNum = date('N', strtotime(date("Y-m-d H:i:s", $startTime)));
if($dayNum == 6 or $dayNum == 7){
$secondsToSubtract += $secondsInDay;
}
$startTime = strtotime(date("Y-m-d H:i:s", $startTime) . " +1 day");
}
$count = $count + 1;
}
return $secondsToSubtract;
}
I was thinking of doing something similar to calculate the after-hours time, but I'm having trouble wrapping my head around it.
Would I just take the start time and add time to it and check it each time to see if it's greater than the business closing time? Is it simpler than I'm making it? Is there a mysql solution I'm not aware of?
Thanks in advance!

Calculating difference between dates

I need your help in how to subtract the last_modified and the final_manuscript_date in the following array:
Array (
[chapters_id] => 10736
[last_modified] => 2010-12-21 15:01:55
[steps_id] => 3
[sub_step_id] => 0
[steps_position] => 1
[final_manuscript_date] => 2010-09-27
)
So I can in this case get a value of N days between the dates 2010-12-21 and 2010-09-27?
Can't you simply do:
$diff = strtotime($arr["final_manuscript_date"]) - strtotime($arr["last_modified"]);
$days = $diff / 84600; // to get # of days, you can round them off or use ceil/floor
If you have 5.3+:
$date1 = new DateTime("2010-09-27");
$date2 = new DateTime("2010-12-21");
$interval = $date1->diff($date2);
echo $interval->d //returns days.
Have you checked strtotime?
http://php.net/manual/en/function.strtotime.php

Categories