miscalculating times - strtotime, date() - PHP - php

Calculating time using date and strtotime functions.
$starttime = '11:55';
$endtime = '13:01'; //or '1:01'
$totaltime = date("i",strtotime($endtime) - strtotime($starttime));
I don't know why, but echo $totaltime giving 06 instead of 66
Its working fine on other time frames. i.e for 12:30, 13:30
Thanks for any help.

Your return value is formatted as a new time output (because of the date() function)
As you are only requesting the number of minutes in the formatted time, it's only returning that part.
If you want to see the hours and minutes, output using h:
$totaltime = date("H:i",strtotime($endtime) - strtotime($starttime));
This will return "01:06".
If you need the actual number of minutes between two dates (so you want 66 as outcome) then you're not looking for a formatted time-string as an outcome, but rather a regular integer holding the number of minutes. This you can calculate from your earlier calculation, like this:
// divide total seconds between these points by 60, round down.
$totalMinutes = floor ( ( strtotime($endtime) - strtotime($starttime) ) / 60 );

Because date("i") only shows minutes from 0 to 59.
PHP date manual
A possible solution:
$totaltime = (strtotime($endtime) - strtotime($starttime)) / 60;

<?php
$starttime = '11:55';
$endtime = '13:01';
echo $totaltime (strtotime($endtime) - strtotime($starttime)) / 60;
echo $totaltime = floor ((strtotime($endtime) - strtotime($starttime)) / 60);
?>

Related

Unix time difference in minutes gives unexpected results

I have the following simple code for testing:
$start_time_unix = time();
$end_time_unix = time();
$seconds_diff = $end_time_unix - $start_time_unix;
$duration = round(abs($seconds_diff/1000) / 60,2);
When i store it in MySQL (int), the results are big values like 25634 even for a few seconds. How can i get the minutes, even in fraction of minutes?? What is wrong with my code above ??
First of all int cannot store fractions, so you will probably want to use float or double instead.
But why are you dividing by 1000. $seconds_diff consists of a seconds, so dividing by 60 will give you fraction of a minute.
For example: If $seconds_diff is a value of 13 [seconds]:
$duration_in_minutes = round($seconds_diff / 60, 2);
$duration_in_milliseconds = $seconds_diff * 1000;
If it is your goal to use milliseconds then use microtime() instead of time():
http://php.net/manual/de/function.microtime.php
Recommendation
Just measure the time with microtime() and directly store the result in the database without rounding, dividing or formatting. Then later on, do the formatting when you have to output it. This will give you more precise results and more freedom.
$start_time = microtime();
…
$end_time = microtime();
$duration = $end_time - $start_time; // duration in milliseconds --> save to database
When outputting, for example:
$duration = get_duration_from_database(); // pseudo function
printf('%.2f minutes', $duration / 1000 / 60);
The time() function returns the current Unix timestamp in seconds. There is no need to divide it by 1000. Since MySQL is expecting an integer, you must round to 0 decimal places:
$seconds_diff = abs($end_time_unix - $start_time_unix);
$duration = round($seconds_diff / 60, 0);

PHP: Wrong Time Calculation

I am working on a project and writing a function to add two different times. The times are stored in database as a string.
I'm:
Pulling value from db
converting it into time using strtotime
adding times using date function
Here is my code:
$time_1 = '1:00';
$time_2 = '0:05';
//should be 1:05, whereas it prints 04:05
echo date("H:i", strtotime($time_1) + strtotime($time_2));
Please tell me, what is wrong with above code and how it can be fixed?
Thanks
Your problem is because strtotime returns the number of seconds since the Unix Epoch (Jan 1 1970). So what you are getting is not values of 60 and 5, but something more like 1537570800 and 1537567500. When you add those two values together, you end up with a date far in the future, with what looks effectively like a random time. To compensate for this, you need to subtract the value of strtotime at the start of the day to make the second time a relative time e.g.:
echo date("H:i", strtotime($time_1) + strtotime($time_2) - strtotime('00:00'));
Output:
01:05
Update
Since it turns out that the sum of the two times can exceed 24 hours, the above code will not work (the maximum time it will display is 23:59 before rolling over to 00:00. So it is necessary to convert both times to a relative number of minutes to the start of the day, add them and then display as hours and minutes:
$time_1 = '12:00';
$time_2 = '14:30';
$time_sum = (strtotime($time_1) + strtotime($time_2) - 2 * strtotime('00:00')) / 60;
printf('%02d:%02d', intdiv($time_sum, 60), $time_sum % 60);
Output:
26:30
Use DateTime::createFromFormat function, and taking ideas from Adding two DateTime objects in php
$time_1 = '1:00';
$time_2 = '0:05';
$t1 = DateTime::createFromFormat('G:i', $time_1);
$t2 = DateTime::createFromFormat('G:i', $time_2);
$interval1 = $t1->diff(new DateTime('00:00:00')) ;
$interval2 = $t2->diff(new DateTime('00:00:00')) ;
$e = new DateTime('00:00');
$f = clone $e;
$e->add($interval1);
$e->add($interval2);
$total = $f->diff($e)->format("%H:%I:%S");
Additional Details:
G and H 24-hour format of an hour with or without leading zeros
i Minutes with leading zeros 00 to 59

Multiple hour by a number

I have something like that for example: 01:06:22 this represents 1hour, 6minutes and 22seconds. I want to take that, and multiple it by 6 and add it to some other hour such as 04:23 which is 4AM and 23Minutes not 4hours and 23 minutes.
Basically, as a result I expect that:
01:06:22
* 6 = 6hours 38minutes canceling the remaining seconds which are 12 in this case
Now, I want to take that and append it to other hour, 04:23 in this case, so the result would be:
11:01.
I have no clue how to start and do it, unfortunately.
Any help is appriciated!
Clarifications
The time that I have to multiple by 6 will never exceed 2 hours.
All the times are in the same format.
With DateTime it is simple:
$time = '01:06:22';
$dateSeconds = new DateTime("1970-01-01 $time UTC");
$seconds = $dateSeconds->getTimestamp() * 6;
$interval = new DateInterval('PT'.$seconds.'S');
$date = new DateTime('1970-01-01 04:23:00 UTC');
$date->add($interval);
echo $date->format('H:i:s');
Other solution with strtotime and gmdate. (Similar to Suresh but working):
$date = strtotime('1970-01-01 01:06:22 UTC');
$add = strtotime('1970-01-01 04:23:00 UTC');
$date = (($date*6)+$add);
echo gmdate('H:i:s', $date);
This is a solution if you want to implement it yourself.
The thing about timecode is that it can become really heavy with the if the if conditions etc if you don't do it right.
The best Way I thought of to deal with this is to convert everything to second.
so 01:06:22 would become:
numberOfSecond = 22 + 06 * 60 + 01 * 60 * 60
How to get the 22, 06 etc from the String? You can use Regex.
What you will need:
a function to extract the different values (hours, minute, second)
a function to convert the timecode into second
a function to convert back into timecode
the functions to multiply, add etc...
You might want to create a class for it.
You can try like this:
$date = strtotime('01:06:22');
$add = strtotime('00:04:23');
$date = ($date*6)+$add;
echo date('H:i:s', $date);
Note: Code is not tested.
First of all you want to multiply a time span by a factor. The easiest way to do this is to convert the span to seconds and do a straight multiply:
$date =DateTime::createFromFormat('!H:i:s', '01:06:22', new DateTimeZone('UTC'));
$seconds = $date->getTimestamp();
This code works by pretending that the time is a moment during the Unix epoch start so that it can then get the number of seconds elapsed since the epoch (the timestamp). That number is equal to the duration of the time span in seconds. However, it is vitally important that the input is interpreted as UTC time and not as something in your local time zone.
An equivalent way of doing things (as long as the input is in the correct format) which is lower-tech but perhaps less prone to bugs would be
list($h, $m, $s) = explode(':', '01:06:22');
$seconds = $h * 3600 + $m * 60 + $s;
Now the multiplication:
$seconds = $seconds * 6;
If you want to only keep whole minutes from the time you can do so at this stage:
$seconds = $seconds - $seconds % 60;
The final step of adding the result to a given "time" is not clearly specified yet -- does the reference time contain date information? What happens if adding to it goes over 24 hours?
Self explanatory :
$initialTime = '01:06:22';
$timeToAdd = '04:23';
$initialTimeExploded = explode( ':' ,$initialTime );
$initialTimeInMintues = ( $initialTimeExploded[0] * 60 ) + $initialTimeExploded[1];
$initialTimeInMintuesMultipliedBySix = $initialTimeInMintues * 6;
$timeToAddExploded = explode( ':' ,$timeToAdd );
$timeToAddExplodedInMintues = ( $timeToAddExploded[0] * 60 ) + $timeToAddExploded[1];
$newTimeInMinutes = $initialTimeInMintuesMultipliedBySix + $timeToAddExplodedInMintues;
$newTime = floor( $newTimeInMinutes / 60 ) .':' .($newTimeInMinutes % 60);
echo $newTime;
Result :
10:59

Adding hours in PHP

I figured this would be a very simple problem but I haven't found a solution anywhere.
I am creating a scheduling program in PHP and mySQL. The shifts have a startTime and endTime, each of which are stored as TIME in mySQL.
I want to add up the total hours for an employee during the week, so I tried:
$shifts = [...] //shifts for the week
$totalTime = 0; //I've also tried "0:0:0" and strtotime("0:00:00");
for($d = 0; $d < 7; $d++){
$start = strtotime($shift_types[$shifts[$d]]['ShiftType']['start_time']);
$end = strtotime($shift_types[$shifts[$d]]['ShiftType']['end_time']);
echo date("g:ia", $start) . ' / ' . date("g:i a", $end);
$totalTime += ($end-$start);
}
}
The problem with this, is that $totalTime doesn't come out to any reasonable number. I think this is because PHP is treating $totalTime as a timestamp since 1970, which would result in something completely different. All I really want is a value of net hours, it doesn't need to have any date-ish values associated with it.
I should mention that I'm displaying the total time with
echo date("g:i", $totalTime);
When it is run with a start of 9:30:00 and an end of 16:15:00, it displays "1:45".
When the total time isn't touched (because there are no shifts), it displays "7:00".
strtotime returns a Unix timestamp, the number of seconds since the epoch represented by that time. So working with seconds (and starting $totalTime at zero) is the correct approach. If you want the number of hours, you need to: $totalTime = $totalTime / (60 * 60); after your loop (divide by 3600 seconds / hour).
I think this does what you want to do:
$t1 = strtotime("2013-01-01 00:00:00");
$t2 = strtotime("2013-01-15 00:00:00");
echo round(($t2-$t1)/3600) ." hours". PHP_EOL;
Or you could look to use two DateTime objects and the diff() method as described in my blog post http://webmonkeyuk.wordpress.com/2011/05/04/working-with-date-and-time-in-php/

PHP time substraction

I am trying to substract 24 hours time format and then convert it into minutes but it does not work well.
Here is my code
$time1 = '2010-08-05 23:00:00';
$time2 = '2010-08-05 00:00:00';
echo round( (strtotime($time2) - strtotime($time1)) / 60);
it will display this -1380.
if you put 1-23 hour in time2 it will work. I tried to convert time in 12 hours but it didn't work.
Any help would be greatly appreciated.
The result is in minutes not in hours.
strtotime() returns a result in seconds (in the Unix timestamp format). You will need to divide by 3600 to convert to hours.
Try this:
$time1 = '2010-08-05 23:00:00';
$time2 = '2010-08-05 00:00:00';
echo abs ( round( (strtotime($time2) - strtotime($time1)) / 3600) );
The abs() function returns an absolute value. In this case, the final result is 23 hours.
I think this is what you are trying to get:
echo round( (strtotime($time1) - strtotime($time2)) / 3600);
Firstly you were subtracting the times the wrong way round, then you were only dividing by 60 which was giving you your answer in minutes.

Categories