$array = [ '00:09:45', '00:50:05', '00:01:05', ]
I tried this calculating time but it is not working.
I understand that by calculate he meant addition.
(Nuances related to translation). Below is an example function in Laravel that adds these times from an array. You should use Carbon for this purpose.
use Carbon\Carbon;
function addTimes($times) {
$totalTime = Carbon::createFromTime(0, 0, 0);
foreach ($times as $time) {
$time = Carbon::createFromFormat('H:i:s', $time);
$totalTime->addSeconds($time->secondsSinceMidnight());
}
return $totalTime;
}
$times = [ '00:09:45', '00:50:05', '00:01:05', ];
$totalTime = addTimes($times);
echo $totalTime->format('H:i:s');
I believe you want sum the durations of time. We can transform it in a collection and reduce it by adding the times.
use Carbon/Carbon;
$array = collect(['12:09:45', '11:50:05', '07:01:05']);
$total = $array->reduce(function ($time, $timeNext){
$carbonTimeNext = new Carbon($timeNext);
$time->addHours($carbonTimeNext->format('H'))
->addMinutes($carbonTimeNext->format('i'))
->addSeconds($carbonTimeNext->format('s'));
return $time;
}, new Carbon('00:00:00'));
echo $total->shortAbsoluteDiffForHumans(new Carbon('00:00:00'), 6);
//output: 1d 7h 55s
Summing times can be done using Carbon like so (less is more):
use Carbon\Carbon;
$times = ['00:09:45', '00:50:05', '00:01:05'];
$time = Carbon::createFromTimestamp(array_reduce($times, function($sum, $item) {
return $sum + Carbon::createFromTimestamp(0)->setTimeFromTimeString($item)->timestamp;
}));
Note: the resulting $time variable is a Carbon date from unix time = 0 with the times added from your array.
The sum of seconds from your array can thus be retrieved using the timestamp property, which is the amount of seconds since the start of the unix epoch:
$sumSeconds = $time->timestamp;
// 3655
Displaying it as a string goes as follows:
use Carbon\CarbonInterface;
$str = $time->diffForHumans(Carbon::createFromTimestamp(0), CarbonInterface::DIFF_ABSOLUTE, false, 2);
// "1 hour 55 seconds"
Related
I try to get an average of given dates but I failed when dates are from two different years. I need something like this
given dates:
2017-06-1
2017-06-3
2017-06-4
2017-06-3
2017-06-5
output : 2017-06-4
this is my code:
$total = 0;
foreach ($dates as $date) {
$total+= date('z', strtotime($date))+1;
}
$avg_day = $total/sizeof($dates);
$date = DateTime::createFromFormat('z Y', $avg_day . ' ' . date("Y"));
but my code is not working for
given dates:
2016-12-29
2016-12-31
2017-01-1
2017-01-5
2017-01-3
You can work with timestamp of the date and use avg() method of the Illuminate\Support\Collection
$dates = [
'2016-12-29', '2016-12-31', '2017-01-1', '2017-01-5', '2017-01-3'
];
$dateCollection = collect();
foreach($dates as $date){
$dateCollection->push((new \DateTime($date))->getTimestamp());
}
$averageTimestamp = $dateCollection->avg(); //timestamp value
$averageDate = date('Y-m-d', $average);
Or using Carbon package:
$dateCollection->push(Carbon::parse($date)->timestamp);
...
$averageDate = Carbon::createFromTimestamp($average)->toDateString();
Your code is not working for your base dates. The correct output for
2017-06-1 2017-06-3 2017-06-4 2017-06-3 2017-06-5
is
2017-06-03
According to OpenOffice calc, and overall logic (a date is represented by epoch number)
Check out this script
$dates = ['2017-06-1 ', '2017-06-3', '2017-06-4', '2017-06-3', '2017-06-5'];
$dates = array_map('strtotime', $dates);
$average = date('Y-m-d', array_sum($dates) / count($dates)); // 2017-06-03 (1496490480)
echo $average;
Keep simple tasks simple
I think you have problem with averaging year. So, You can do this to get average.
Just an algorithm:
Find smallest date among your dates at first as $smallest
Initiate a variable $total = 0;
Add difference of each date in days with smallest date.
Find average from total.
Add this total to smallest date.
Here, You have smallest as $smallest = '2016-12-29'
$total = 0;
$dates = ['2016-12-29', '2016-12-31', '2017-01-1', '2017-01-5', '2017-01-3'];
$smallest = min($dates);
$smallest = Carbon::parse($smallest);
foreach($dates as $date){
$d = Carbon::parse($date);
$total = $total+$smallest->diffInDays($d);
}
$average_day = $total/sizeof($dates);
$average_date = $smallest->addDays($average_day);
Hope, This might help you.
I have a requirement where I need to extract 5 points from a Unix time stamp or PHP time stamp range.
For Example,
From 2014-06-26 07:53:26 to 2014-06-27 07:52:46.
I need five points from these two dates in exact or approximate intervals, to chart using pChart.
Currently My Code is
$diff = $mintime->diff($maxtime);
$range = max($timestamps) - min($timestamps);
$cnt = count($timestamps);
$temp = ceil($range * (20/100));
for($i=0;$i<$cnt;$i++)
{
if($i%($cnt/5) == 0)
$point[$i] = gmdate("Y-m-d H:i:s",min($timestamps) + $temp * ($i+1));
else
$point[$i] = null;
}
But My Code returns erratic values. I know the problem is with the temp variable. Help me solve this.
Thanks
Try this:
$from = '2014-06-26 07:53:26';
$to = '2014-06-27 07:52:46';
$diff_stamp = strtotime($to) - strtotime($from);
$range = range(strtotime($from), strtotime($to), $diff_stamp/4);
Here, $range is an array of timestamps. To convert each back to a date, you could use array_map:
$range = array_map(function($a){return date('Y-m-d H:i:s', $a);}, $range);
See Demo Updated
Resources:
strtotime(), range(), array_map()
$splitter=($timestamp1-$timestamp2);
$timestamp_between=array();
for($i=0;$i<5;$i++) $timestamp_between[]=$timestamp1+($i*$splitter);
print_r($timestamp_between);
I have two Zend_Date that represent an interval :
$start = new Zend_Date($punch->getStart());
$end = new Zend_Date($punch->getEnd());
$nbHours = $start->sub($end , Zend_Date::HOUR);
$nbMinutes = $start->sub($end , Zend_Date::MINUTE);
$hoursTotal = $nbHours->get(Zend_Date::HOUR);
$minutesTotal = $nbMinutes->get(Zend_Date::MINUTE);
Is there an simple way to split the interval by day of the week with Zend_Date when the interval > 24 hours?
For example, if I have an interval from Monday 8am to Tuesday 4:30pm, I would like to have an array containing monday = 16h and tuesday = 16:30.
You don't need to use Zend_Date for this, in fact it is probably better not to. You should use the date/time classes in PHP instead.
If I understand your question correctly you want an array of days and the hours worked for those days.
I first created a mock class to reflect your code example, I have assumed it is returning timestamps:-
class Punch
{
public function getStart()
{
return time();
}
public function getEnd()
{
return strtotime('+36 hours 45 minutes');
}
}
Then we set up the DateTime objects-
$Punch = new Punch();
$start = new DateTime();
$start->setTimestamp($Punch->getStart());
$end = new DateTime();
$end->setTimestamp($Punch->getEnd());
Then we use a DateInterval object to generate our iterable DatePeriod:-
$interval = new DateInterval('PT1M');
$minutes = new DatePeriod($start, $interval, $end);
Then we simply iterate over it counting the minutes worked in each day:-
$format = 'l';
foreach($minutes as $minute){
if(!isset($result[$minute->format($format)])) $result[$minute->format($format)] = 0;
$result[$minute->format($format)]++;
}
See the manual page for acceptable formats.
We now have the number of minutes worked in each day, converting them to hours is trivial:-
foreach($result as $key => $r){
$result[$key] = $r/60;
}
var_dump($result);
Output (Obviously, you will get a different result running it at a different time) :-
array
'Monday' => float 17.483333333333
'Tuesday' => float 19.266666666667
So on Monday 17.48 hours were worked and 19.27 on Tuesday.
Alternatively:-
foreach($result as $key => $r){
$result[$key] = floor($r/60) . ':' . $r % 60;
}
Would give the following output if that is closer to what you want:-
array
'Monday' => string "17:29"
'Tuesday' => string "19:16"
That's the simplest way I can think of doing it.
So I have an array of podcast lengths in 30:13 (minutes:seconds) format that I want to first convert to a valid UNIX timestamp and second to format this timestamp into something readable like "30 mins 13s".
My convert to timestamp function looks like this:
public function duration($str) {
$a = explode(':', $str);
$v = (($a[0]*60)+$a[1]);
return $v;
}
The problem comes in when I try to format this with date('H:i:s', $v) which produces numbers like "17:35:50" when there is no way in hell the podcast is 17 hours long. What am I doing wrong?
UNIX timestamps are not meant for calculating durations, they represent a specific time as seconds since the epoch (beginning of the year 1970). If you pass a very low value to functions such as date() that expect a timestamp, you will get a date from the early 1970's. You'll have to do the time formatting manually.
Edit: Note that if you lived in the GMT timezone you would get the results you expected. This is because date() takes into account your current timezone when calculating the dates generated from timestamps.
Just format it to readable string.
$duration = '30:13';
list($min, $sec) = explode(':', $duration);
echo "{$min}mins {$sec}s"; // 30mins 13s
This should do the job you want. Timestamps are something differnt, see http://en.wikipedia.org/wiki/Timestamp
// $str has the format 'mm:ss'
public function duration($str) {
list($min, $sec) = explode(':', $str);
return $min . ' mins ' . $sec . ' sec';
}
Use Simple Regex
function duration($str)
{
return preg_replace('/^([0-9]{2})\:([0-9]{2}$)/', '$1 mins $2s', $str);
}
echo duration("30:33");
OUTPUT
30 mins 33s
Hope this helps you. Thanks!!
you can try for hh:mm:ss
list($hours,$mins,$secs) = explode(':', $yourtime);
echo $hours.' hours '.$mins .'minuts'. $secs .'seconds';
may this work
Unix timestamp gives you the amount of seconds passed from January 1 1970 00:00:00, but not time period.
To achieve your task I'd do:
$str = '30:13';
function duration($str) {
$a = explode(':', $str);
$hours = floor($a[0] / 60);
$minutes = $a[0] - $hours * 60;
$seconds = $a[1];
$result = '';
if($hours) {
$result .= "$hours hours ";
}
if($minutes) {
$result .= "$minutes minutes ";
}
return "$result$seconds seconds";
}
var_dump(duration($str));
You can use a DateInterval object.
function getInterval($durationString) {
$parts = explode(':', $durationString);
$min = $parts[0];
$sec = $parts[1];
$interval = new DateInterval("PT{$min}M{$sec}S");
return $interval;
}
$interval = getInterval('30:12');
echo $interval->format('%imins %ss');
I'm assuming you're using a duration time format with only minutes and seconds, of course you can modify the code if you need also hours.
Hi All I'm trying to calculate elapsed time in php. The problem is not in php, it's with my mathematical skills. For instance:
Time In: 11:35:20 (hh:mm:ss), now say the current time is: 12:00:45 (hh:mm:ss) then the time difference in my formula gives the output: 1:-34:25. It should actually be: 25:25
$d1=getdate();
$hournew=$d1['hours'];
$minnew=$d1['minutes'];
$secnew=$d1['seconds'];
$hourin = $_SESSION['h'];
$secin = $_SESSION['s'];
$minin = $_SESSION['m'];
$h1=$hournew-$hourin;
$s1=$secnew-$secin;
$m1=$minnew-$minin;
if($s1<0) {
$s1+=60; }
if($s1>=(60-$secin)) {
$m1--; }
if($m1<0) {
$m1++; }
echo $h1 . ":" . $m1 . ":" . $s1;
Any help please?
EDIT
Sorry I probably had to add that the page refreshes every second to display the new elapsed time so I have to use my method above. My apologies for not explaining correctly.
This will give you the number of seconds between start and end.
<?php
// microtime(true) returns the unix timestamp plus milliseconds as a float
$starttime = microtime(true);
/* do stuff here */
$endtime = microtime(true);
$timediff = $endtime - $starttime;
?>
To display it clock-style afterwards, you'd do something like this:
<?php
// pass in the number of seconds elapsed to get hours:minutes:seconds returned
function secondsToTime($s)
{
$h = floor($s / 3600);
$s -= $h * 3600;
$m = floor($s / 60);
$s -= $m * 60;
return $h.':'.sprintf('%02d', $m).':'.sprintf('%02d', $s);
}
?>
If you don't want to display the numbers after the decimal, just add round($s); to the beginning of the secondsToTime() function.
Using PHP >= 5.3 you could use DateTime and its method DateTime::diff(), which returns a DateInterval object:
$first = new DateTime( '11:35:20' );
$second = new DateTime( '12:00:45' );
$diff = $first->diff( $second );
echo $diff->format( '%H:%I:%S' ); // -> 00:25:25
Keep track of your time using the 'time()' function.
You can later convert 'time()' to other formats.
$_SESSION['start_time'] = time();
$end_time = time();
$end_time - $_SESSION['start_time'] = 65 seconds (divide by 60 to get minutes)
And then you can compare that to another value later on.
Use microtime if you need millisecond detail.
You can implement the solutions shown, but I'm fond of using the phptimer class (or others, this wheel has been invented a few times). The advantage is that you can usually define the timer to be active or not, thereby permitting you to leave the timer calls in your code for later reference without re-keying all the time points.
For high resolution time, try using monotonic clock: hrtime
<?php
$time = -hrtime(true);
sleep(5);
$end = sprintf('%f', $time += hrtime(true));
?>
Difference between CLOCK_REALTIME and CLOCK_MONOTONIC?