Multiple hour by a number - php

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

Related

Formating integers in percentage in php

I have two integers that are $hours = 74 and $minutes = 20, the format I need to get them in is following: hours and minutes (without any spacing) in percentage of one hour. So in this case the final result should be 7433.
Just to make it more clear if the two numbers would be $hours = 74 and $minutes = 30, the final result should be 7450.
I have been trying to look for similar functions, but without any success.
Any help or guidance is much appreciated.
So really what you are looking for is $result = $hours . floor($minutes/60*100); ?
Or if you need the leading zeroes: $result = str_pad($hours,2,'0') . str_pad(floor($minutes/60*100),2,'0');
Save yourself the pain of coming up with code that handles cases where the value of $minutes >= 60 by using the DateTimeInterface objects. I admit, they may seem overkill in this situation, but they are very sturdy and reliable. Plus, if ever you'd want to add days, weeks, months, years or seconds to this code, the DateTimeInterface classes are already equipped for the job:
$now = new DateTime();
$comp = clone $now;
//2 identical datetime instances
//add hours + minutes to either one
$comp->add(
sprintf(
'PT%dH%dM',
$hours,
$minuts
)
);
//get difference in seconds
$diff = $comp->getTimeStamp() - $now->getTimeStamp();
//or echo, I used printf to limit the number of decimals to 2
printf(
'%.2f hours difference'
$diff/3600 //1 hour === 3600 seconds
);
Just browse the DateTime docs, and other classes/interfaces like DateInterval and others implementing the DateTimeInterface.
Just for completeness, here's how I'd set about doing this "manually"
$decimalT = $hours + floor($minutes/60) + ($minutes%60)/60
//add hours in case $minutes>= 60
//floor($minutes/60);
//get remainder minutes, converted to decimal hours
//($minutes%60)/60;
printf(
'%d hours + %d seconds == %.2f hours',
$hours,
$minutes,
$decimalT
);
Use this snippet of code:
$hours = 74;
$minutes = 20;
$totalMinutes = $hours * 60 + $minutes;
$percentage = floor(($totalMinutes * 100) / 60);
var_dump($percentage);

Transform DateTime variable into minutes

There is the following variable:
$datetime = '2012-09-09 01:40';
I need to extract hours and minutes, and then to transform them into minutes. In this example, I would need to get 100 (1 hr 40 min = 60 min + 40 min). How can I quickly do this using PHP functions?
The strtotime() and date() functions are not recommended anymore. Use the DateTime class.
$datetime = '2012-09-09 01:40';
$d = new DateTime($datetime);
var_dump( $d->format('G') * 60 + $d->format('i') );
$string = '2012-09-09 01:40';
$epoch = strtotime($string);
echo date('i', $epoch) + (60 * date('H', $epoch));
Outputs 100
Basically what happens here is the string date gets converted to Unix/Epoch time. Then, using date() it adds the number of minutes (i) to 60 times the number of hours (h).
$datetime = strtotime('2012-09-09 01:40');
$hour = date('H',$datetime);
$min = date('i',$datetime);
echo ($hour*60 + $min);
You can use preg_split like this:
$parts=preg_split("/(\d\d):(\d\d)/",$datetime,-1,PREG_SPLIT_DELIM_CAPTURE);
$mins=($parts[1]*60)+$parts[2];
Now $mins=100 when $datetime is like in your post

How to round unix timestamp up and down to nearest half hour?

Ok so I am working on a calendar application within my CRM system and I need to find the upper and lower bounds of the half an hour surrorunding the timestamp at which somebody entered an event in the calendar in order to run some SQL on the DB to determine if they already have something booked in within that timeslot.
For example I have the timestamp of 1330518155 = 29 February 2012 16:22:35 GMT+4
so I need to get 1330516800 and 1330518600 which equal 16:00 and 16:30.
If anyone has any ideas or think I am approaching developing the calendar in a stupid way let me know! Its my first time on such a task involving so much work with times and dates so any advice appreciated!
Use modulo.
$prev = 1330518155 - (1330518155 % 1800);
$next = $prev + 1800;
The modulo operator gives the remainder part of division.
I didn't read the questions clearly, but this code will round to the nearest half hour, for those who don't need the range between the two. Uses some of SenorAmor's code. Props and his mad elegant solution to the correct question.
$time = 1330518155; //Or whatever your time is in unix timestamp
//Store how many seconds long our rounding interval is
//1800 equals one half hour
//Change this to whatever interval to round by
$INTERVAL_SECONDS = 1800; //30*60
//Find how far off the prior interval we are
$offset = ($time % $INTERVAL_SECONDS);
//Removing this offset takes us to the "round down" half hour
$rounded = $time - $offset;
//Now add the full interval if we should have rounded up
if($offset > ($INTERVAL_SECONDS/2)){
$nearestInterval = $rounded + $INTERVAL_SECONDS;
}
else{
$nearestInterval = $rounded
}
You could use the modulo operator.
$time -= $time % 3600; // nearest hour (always rounds down)
Hopefully this is enough to point you in the right direction, if not please add a comment and I'll try to craft a more specific example.
PHP does have a DateTime class and a whole slough of methods that it provides. You could use these if you like, but I find it easier to use the built-in date() and strtotime() functions.
Here's my solution:
// Assume $timestamp has the original timestamp, i.e. 2012-03-09 16:23:41
$day = date( 'Y-m-d', $timestamp ); // $day is now "2012-03-09"
$hour = (int)date( 'H', $timestamp ); // $hour is now (int)16
$minute = (int)date( 'i', $timestamp ); // $minute is now (int)23
if( $minute < 30 ){
$windowStart = strtotime( "$day $hour:00:00" );
$windowEnd = strtotime( "$day $hour:30:00" );
} else {
$windowStart = strtotime( "$day $hour:30:00" );
if( ++$hour > 23 ){
// if we crossed midnight, fix the date and set the hour to 00
$day = date( 'Y-m-d', $timestamp + (24*60*60) );
$hour = '00';
}
$windowEnd = strtotime( "$day $hour:00:00" );
}
// Now $windowStart and $windowEnd are the unix timestamps of your endpoints
There are a few improvements that can be made on this, but that's the basic core.
[Edit: corrected my variable names!]
[Edit: I've revisited this answer because, to my embarrassment, I realized that it didn't handle the last half-hour of a day correctly. I've fixed that issue. Note that $day is fixed by adding a day's worth of seconds to the timestamp -- doing it this way means we don't have to worry about crossing month boundaries, leap days, etc. because PHP will format it correctly for us regardless.]
If you need to get the current time and then apply the rounding (down) of the time, I would do the following:
$now = date('U');
$offset = ($now % 1800);
$now = $now-$offset;
for ($i = 0;$i < 24; $i++)
{
echo date('g:i',$now);
$now += 1800;
}
Or you could round up by adding the offset, and do something more than just echo the time. The for loop then displays the 12 hours of increments. I used the above in a recent project.
I'd use the localtime and the mktime function.
$localtime = localtime($time, true);
$localtime['tm_sec'] = 0;
$localtime['tm_min'] = 30;
$time = mktime($localtime);
Far from my best work... but here's some functions for working with string or unix time stamp.
/**
* Takes a timestamp like "2016-10-01 17:59:01" and returns "2016-10-01 18:00"
* Note: assumes timestamp is in UTC
*
* #param $timestampString - a valid string which will be converted to unix with time()
* #param int $mins - interval to round to (ex: 15, 30, 60);
* #param string $format - the format to return the timestamp default is Y-m-d H:i
* #return bool|string
*/
function roundTimeString( $timestampString, $mins = 30, $format="Y-m-d H:i") {
return gmdate( $format, roundTimeUnix( time($timestampString), $mins ));
}
/**
* Rounds the time to the nearest minute interval, example: 15 would round times to 0, 15, 30,45
* if $mins = 60, 1:00, 2:00
* #param $unixTimestamp
* #param int $mins
* #return mixed
*/
function roundTimeUnix( $unixTimestamp, $mins = 30 ) {
$roundSecs = $mins*60;
$offset = $unixTimestamp % $roundSecs;
$prev = $unixTimestamp - $offset;
if( $offset > $roundSecs/2 ) {
return $prev + $roundSecs;
}
return $prev;
}
This is a solution using DateTimeInterface and keeping timezone information etc. Will also handle timezones that are not a multiple of 30 minutes offset from GMT (e.g. Asia/Kathmandu).
/**
* Return a DateTimeInterface object that is rounded down to the nearest half hour.
* #param \DateTimeInterface $dateTime
* #return \DateTimeInterface
* #throws \UnexpectedValueException if the $dateTime object is an unknown type
*/
function roundToHalfHour(\DateTimeInterface $dateTime)
{
$hours = (int)$dateTime->format('H');
$minutes = $dateTime->format('i');
# Round down to the last half hour period
$minutes = $minutes >= 30 ? 30 : 0;
if ($dateTime instanceof \DateTimeImmutable) {
return $dateTime->setTime($hours, $minutes);
} elseif ($dateTime instanceof \DateTime) {
// Don't change the object that was passed in, but return a new object
$dateTime = clone $dateTime;
$dateTime->setTime($hours, $minutes);
return $dateTime;
}
throw new UnexpectedValueException('Unexpected DateTimeInterface object');
}
You'll need to have created the DateTime object first though - perhaps with something like $dateTime = new DateTimeImmutable('#' . $timestamp). You can also set the timezone in the constructor.
Math.round(timestamp/1800)*1800
As you probably know, a UNIX timestamp is a number of seconds, so substract/add 1800 (number of seconds in 30 minutes) and you will get the desired result.
Here's a more semantic method for those that have to make a few of these, perhaps at certain times of the day.
$time = strtotime(date('Y-m-d H:00:00'));
You can change that H to any 0-23 number, so you can round to that hour of that day.

How to find time difference between 2 time vars greater than 24 hours

I need to find how much time is between to time values (their difference) which are over 24:00:00.
For example: how can I calculate the difference between 42:00:00 and 37:30:00?
Using strtotime, strptotime, etc is useless since they cannot go over 23:59:59 ....
$a_split = explode(":", "42:00:00");
$b_split = explode(":", "37:30:00");
$a_stamp = mktime($a_split[0], $a_split[1], $a_split[2]);
$b_stamp = mktime($b_split[0], $b_split[1], $b_split[2]);
if($a_stamp > $b_stamp)
{
$diff = $a_stamp - $b_stamp;
}else{
$diff = $b_stamp - $a_stamp;
}
echo "difference in time (seconds): " . $diff;
then use date() to convert seconds to HH:MM:SS if you want.
Date/Time variables and functions are not appropriate here as you're not storing time, but instead a time span of (I assume) hours, minutes, and seconds.
Likely your best solution is going to be to split each time span into their integer components, convert to a single unit (for instance, seconds), subtract them from each other, then re-build an output time span that fits with your application.
I havent tested this, but this might do what you want:
function timediff($time1, $time2) {
list($h,$m,$s) = explode(":",$time1);
$t1 = $h * 3600 + $m * 60 + $s;
list($h2,$m2,$s2) = explode(":",$time2);
$seconds = ($h2 * 3600 + $m2 * 60 + $s2) - $t1;
return sprintf("%02d:%02d:%02d",floor($seconds/3600),floor($seconds/60)%60,$seconds % 60);
}

Get interval seconds between two datetime in PHP?

2009-10-05 18:11:08
2009-10-05 18:07:13
This should generate 235,how to do it ?
With DateTime objects, you can do it like this:
$date = new DateTime( '2009-10-05 18:07:13' );
$date2 = new DateTime( '2009-10-05 18:11:08' );
$diffInSeconds = $date2->getTimestamp() - $date->getTimestamp();
You can use strtotime() to do that:
$diff = strtotime('2009-10-05 18:11:08') - strtotime('2009-10-05 18:07:13')
A similar approach is possible with DateTime objects, e.g.
$date = new DateTime( '2009-10-05 18:07:13' );
$date2 = new DateTime( '2009-10-05 18:11:08' );
$diff = $date2->getTimestamp() - $date->getTimestamp();
PHP Date Time reference is helpful for things like this: PHP Date Time Functions
strtotime() is probably the best way.
$seconds = strtotime('2009-10-05 18:11:08') - strtotime('2009-10-05 18:07:13')
For those worrying about the limitations of using timestamps (i.e. using dates before 1970 and beyond 2038), you can simply calculate the difference in seconds like so:
$start = new DateTime('2009-10-05 18:11:08');
$end = new DateTime('2009-10-05 18:07:13');
$diff = $end->diff($start);
$daysInSecs = $diff->format('%r%a') * 24 * 60 * 60;
$hoursInSecs = $diff->h * 60 * 60;
$minsInSecs = $diff->i * 60;
$seconds = $daysInSecs + $hoursInSecs + $minsInSecs + $diff->s;
echo $seconds; // output: 235
Wrote a blog post for those interested in reading more.
Because of unix epoch limitations, you could have problems compairing dates before 1970 and after 2038. I choose to loose precision (=don't look at the single second) but avoid to pass trough unix epoch conversions (getTimestamp). It depends on what you are doing to do...
In my case, using 365 instead (12*30) and "30" as mean month lenght, reduced the error in an usable output.
function DateIntervalToSec($start,$end){ // as datetime object returns difference in seconds
$diff = $end->diff($start);
$diff_sec = $diff->format('%r').( // prepend the sign - if negative, change it to R if you want the +, too
($diff->s)+ // seconds (no errors)
(60*($diff->i))+ // minutes (no errors)
(60*60*($diff->h))+ // hours (no errors)
(24*60*60*($diff->d))+ // days (no errors)
(30*24*60*60*($diff->m))+ // months (???)
(365*24*60*60*($diff->y)) // years (???)
);
return $diff_sec;
}
Note that the error could be 0, if "mean" quantities are intended for diff. The PHP docs don't speaks about this...
In a bad case, error could be:
0 seconds if diff is applied to time gaps < 1 month
0 to 3 days if diff is applied to time gaps > 1 month
0 to 14 days if diff is applied to time gaps > 1 year
I prefer to suppose that somebody decided to consider "m" as 30 days and "y" as 365, charging "d" with the difference when "diff" walk trough non-30-days months...
If somebody knows something more about this and can provide official documentation, is welcome!
strtotime("2009-10-05 18:11:08") - strtotime("2009-10-05 18:07:13")
The solution proposed by #designcise is wrong when "end date" is before "start date".
Here is the corrected calculation
$diff = $start->diff($end);
$daysInSecs = $diff->format('%r%a') * 24 * 60 * 60;
$hoursInSecs = $diff->format('%r%h') * 60 * 60;
$minsInSecs = $diff->format('%r%i') * 60;
$seconds = $daysInSecs + $hoursInSecs + $minsInSecs + $diff->format('%r%s');
A simple and exact solution (exemplifying Nilz11's comment):
$hiDate = new DateTime("2310-05-22 08:33:26");
$loDate = new DateTime("1910-11-03 13:00:01");
$diff = $hiDate->diff($loDate);
$secs = ((($diff->format("%a") * 24) + $diff->format("%H")) * 60 +
$diff->format("%i")) * 60 + $diff->format("%s");

Categories