Im having a a bit strange problem, Im having this code and on output it adds always one hour more if the second time has 30 or more minutes.
$time1 = '12:00';
$time2 = '13:30';
list($hours, $minutes) = explode(':', $time1);
$startTimestamp = mktime($hours, $minutes);
list($hours, $minutes) = explode(':', $time2);
$endTimestamp = mktime($hours, $minutes);
$seconds = $endTimestamp - $startTimestamp;
$minutes = ($seconds / 60) % 60;
$hours = round($seconds / (60 * 60));
Whats happening here?
Remember the math. Rounding up everything in interval [0.5;1) equals to 1.
round(0.5) = 1
That's why you've +1 hour in case of minutes in [30;60].
Instead of using round use intval as $seconds / (60 * 60) expression always returns a float and we need only the integer part of that result
Related
I got this number: 116041 (is it in milliseconds).
And i want to transform to something like this minuts:seconds:miliseconds
Theoretically that number should transform to something like: 1:56:xx
And I'm trying this code:
$diff = 116041;
$date = date("i:s:u",$diff);
echo $date;
But I'm getting this output:
14:01:000000
date() takes a timestamp integer. The value you are supplying equals Friday, January 2, 1970 8:14:01 AM. Notice the 14:01? That is what you are getting using date("i:s:u",$diff);
Go to Epoch Converter and enter 116041 into the field and you can see it for yourself.
This should be pretty simple math.
// Get the minutes (60000ms per minute)
$milliseconds = 116041;
$minutes = floor(116041 / 60000);
// Find the remaining milliseconds
$milliseconds = $milliseconds % 60000;
// Continue to seconds calculation...
In this case, the date or DateTime route is more complicated. Just do some simple math...
$s = 116041 / 1000;
printf("%d:%02.3f", intdiv($s, 60), fmod($s, 60));
You can try this method. please let me know if it of any help to you.
<?php
function formatMilliseconds($milliseconds) {
$seconds = floor($milliseconds / 1000);
$minutes = floor($seconds / 60);
$hours = floor($minutes / 60);
$seconds = $seconds % 60;
$minutes = $minutes % 60;
$milliseconds = $milliseconds % 1000;
$format = '%u:%02u:%02u.%02u';
$time = sprintf($format, $hours, $minutes, $seconds, $milliseconds);
return rtrim($time, '0');
}
echo formatMilliseconds(2000202123);
?>
I am trying to add total worked hrs for the employees for the 7 days week period below code is not working for me, not sure what am i doing wrong as I am not a PHP expert, idea please?
<?php
$time1 = $row_Roster['sunday_start'];
$time2 = $row_Roster['sunday_end'];
list($hours, $minutes, $seconds) = explode(':', $time1);
$startTimestamp = mktime($hours, $minutes, $seconds);
list($hours, $minutes, $seconds) = explode(':', $time2);
$endTimestamp = mktime($hours, $minutes, $seconds);
$add = $endTimestamp - $startTimestamp;
if($seconds < 0) {
$seconds+=60*60*24;
}
$seconds = $add % 60;
$minutes = ($add / 60) % 60;
$hours = floor($add / (60 * 60));
$sunday = sprintf('%02d:%02d:%02d', $hours, $minutes, $seconds);
echo $sunday;
if ($sunday >8)
echo ('</br><span class="smallred">Long Shift</span>');
?>
does it make sense
list($hours, $minutes, $seconds) = explode(':', $time1);
$Timestamp1 = mktime($hours, $minutes, $seconds);
list($hours, $minutes, $seconds) = explode(':', $time2);
$Timestamp2 = mktime($hours, $minutes, $seconds);
list($hours, $minutes, $seconds) = explode(':', $time3);
$Timestamp3 = mktime($hours, $minutes, $seconds);
list($hours, $minutes, $seconds) = explode(':', $time4);
$Timestamp4 = mktime($hours, $minutes, $seconds);
$add = $Timestamp1 + $Timestamp2 + $Timestamp3 + $Timestamp4;
if($seconds < 0) {
$seconds+=60*60*24;
}
$seconds = $add % 60;
$minutes = ($add / 60) % 60;
$hours = floor($add / (60 * 60));
$total = sprintf('%02d:%02d:%02d', $hours, $minutes, $seconds);
echo $total;
?>
You make this way to complicated.
First just put all your formatted days into an array ($formattedWorkTimeWeekdays).
Then go through each day with array_map() and calculate the total amount of seconds per day and save it in $secondsWorkTimeWeekdays.
After this you can sum all seconds per day together with array_sum() and you get the total amount of work for this week in seconds in the variable $totalSecondsWorkTimeWeek.
And at the end simply calculate the hours, minutes and seconds out of it.
<?php
$formattedWorkTimeWeekdays = [
$monday,
$tuesday,
$wednesday,
$thursday,
$friday,
$saturday,
$sunday,
];
$secondsWorkTimeWeekdays = array_map(function($formattedWorkTimeDay){
list($hours, $minutes, $seconds) = explode(":", $formattedWorkTimeDay);
return ($hours * 3600) + ($minutes * 60) + $seconds;
}, $formattedWorkTimeWeekdays);
$totalSecondsWorkTimeWeek = array_sum($secondsWorkTimeWeekdays);
$hoursWorkTimeWeek = $totalSecondsWorkTimeWeek / 3600;
$minutesWorkTimeWeek = ($totalSecondsWorkTimeWeek % 3600) / 60;
$secondsWorkTimeWeek = ($totalSecondsWorkTimeWeek % 3600 % 60);
echo $total = sprintf('%02d:%02d:%02d', $hoursWorkTimeWeek, $minutesWorkTimeWeek, $secondsWorkTimeWeek);
?>
EDIT:
After your edit your have 2 completely different codes, which aren't related to each other at all. For your first revision I gave the answer above.
Now in your edited code you just seem to have 2 dates. You can just create two DateTime objects and get the difference from them, e.g.
$workTimeStart = new DateTime($row_Roster['sunday_start']);
$workTimeEnd = new DateTime($row_Roster['sunday_end']);
$workTimeDifference = $workTimeStart->diff($workTimeEnd);
echo $workTimeDifference->format("%h hours %i minutes %s seconds");
Instead of calculations and calling sprintf, you can use gmdate function:
//the same code summing the weekdays seconds
$add = $Timestamp1 + $Timestamp2 + $Timestamp3 + $Timestamp4;
print gmdate("H:i:s", $add);
I'm addditioning time value of a schedule.
When The value go over 24:00 I'm begining to have a problem..
Here is a simple example of what i'm trying to do.
$now = strtotime("TODAY");
$time_1 = strtotime('08:00:00') - $now;
$total = $time_1 * 5;
$total = $total + $now;
echo date('H:i', $total);
The echo value is 16:00:00
But it should be 40:00:00
24:00:00 + 16:00:00 = 40:00:00
So I understand that this is 1 day and 16 hours.
How can I echo 40:00:00
Below is your example code working the way you want.
As others have mentioned, you have to do the math yourself for cases like this.
<?php
$now = strtotime("TODAY");
$time_1 = strtotime('08:00:00') - $now;
$total = $time_1 * 5;
$secs = $total%60;
$mins = floor($total/60);
$hours = floor($mins/60);
$mins = $mins%60;
printf("%02d:%02d:%02d", $hours, $mins, $secs);
You can't. date() is intended to produce VALID date/time strings. 40 is not something that would appear in a normal time string. You'll have to use math to generate that time string on your own:
$seconds = $total;
$hours = $seconds % 3600;
$seconds -= ($seconds * 3600);
$minutes = $seconds % 60;
$seconds -= ($seconds * 60);
$string = "$hours:$minutes:$seconds";
The date function is for dates and times, not durations. Since the time is never "40:00", it will never return that string.
You can look into using the DateTimeInterface to get what you want, but it might be simpler just to do the math yourself.
$seconds = $total;
$minutes = (int)($seconds/60);
$seconds = $seconds % 60;
$hours = (int)($minutes / 60);
$minutes = $minutes % 60;
$str = "$hours:$minutes:$seconds";
Say I have the following as a string:
$timeLeft = 00:02:30
I want to be able to subtract 1 second, turning it into 00:02:29.
I have tried
$timeLeft - 1;
But it does nothing.
How can I make it so I can subtract seconds from a string?
You need to convert it to a time, subtract 1 second and reformat, e.g.:
$timeLeft = '00:02:30';
$time = DateTime::createFromFormat('H:i:s', $timeLeft);
$time->sub(new DateInterval('PT1S'));
$timeLeft = $time->format('H:i:s');
Below is dirty code that performs the transformation "manually" by converting the time into seconds in case PHP 5.3+ is not available. It'll certainly misbehave it the number of seconds subtracted is greater than the total.
$timeLeft = '00:02:30';
list($hours, $minutes, $seconds) = explode(':', $timeLeft);
$seconds += $hours*3600 + $minutes*60;
unset($hours, $minutes);
$seconds -= 1; //subtraction
$hours = floor($seconds/3600);
$seconds %= 3600;
$minutes = floor($seconds/60);
$seconds %= 60;
$timeLeft = sprintf("%'02u:%'02u:%'02u", $hours, $minutes, $seconds);
Using strtotime is a good practical solution, but you have to watch out for DST changes:
$tz = date_default_timezone_get(); // save old timezone
date_default_timezone_set('UTC'); // switch to UTC
echo date('H:i:s', strtotime($timeleft) - 1); // perform calculation
date_default_timezone_set($tz); // restore old setting
$time1 = "01:00";
$time2 = "04:55";
list($hours1, $minutes1) = explode(':', $time1);
$startTimestamp = mktime($hours1, $minutes1);
list($hours2, $minutes2) = explode(':', $time2);
$endTimestamp = mktime($hours2, $minutes2);
$seconds = $endTimestamp - $startTimestamp;
$minutes = ($seconds / 60) % 60;
$hours = round($seconds / (60 * 60));
echo $hours.':'.$minutes;
exit;
Outputs 4:55, should be 3:55 ?
Whats wrong here? If it is 01:00 and 02:00, it works fine, but not with the above?
Use floor instead of round...
Or just cast to integer.
$hours = (int) ($seconds / (60 * 60));
Too many calculations when PHP can do it for you with also reducing possibility of error
$time1 = Datetime::createFromFormat("h:i", "01:00");
$time2 = Datetime::createFromFormat("h:i", "04:55");
$diff = $time1->diff($time2);
var_dump($diff->format("%h %i"));
Output
string '3:55' (length=4)
You can also save yourself some time by using strtotime:
$time1 = strtotime("01:00");
$time2 = strtotime("04:55");
$seconds = $time2-$time1;
$minutes = ($seconds / 60) % 60;
$hours = floor($seconds / (60 * 60));
echo $hours.':'.$minutes;
As mentioned, using floor will produce the result you need:
Result
3:55