This question already has answers here:
How do I find the hour difference between two dates in PHP?
(10 answers)
Closed 5 years ago.
I have datetimes in the following format:
Start: 2017-07-16 20:00
End: 2017-07-16 23:30
Start: 2017-07-18 21:30
End: 2017-07-19 00:30
I need to tell from these intervals how many hours (in 0,5 increments) are spent between 18:00-22:00 and 22:00-06:00 in total for a month.
Thanks in advance for any hint.
The current code I have is this, but I'm not sure if it is covering all timeframe possibilities:
<?php
date_default_timezone_set("UTC");
$start = array(
"2017-07-16 21:30:00",
"2017-07-16 18:00:00"
);
$end = array(
"2017-07-17 00:30:00",
"2017-07-16 18:30:00"
);
$amount_low = 0;
$amount_high = 0;
for($i = 0; $i < sizeof($start); $i++) {
$start_time = date("H:i:s", strtotime($start[$i]));
$end_time = date("H:i:s", strtotime($end[$i]));
$start_date = date("Ymd", strtotime($start[$i]));
$end_date = date("Ymd", strtotime($end[$i]));
// getting chunk before 22:00 if
if(
(strtotime($start[$i]) >= strtotime($start_date . " 18:00") && strtotime($start[$i]) < strtotime($start_date . " 22:00"))
&&
$start_date < $end_date
) {
$interval_low = strtotime($start_date . " 22:00") - strtotime($start[$i]);
$amount_low += ceil($interval_low / 1800) / 2;
}
//amount_high
if(strtotime($start[$i]) > strtotime($start_date . " 22:00") && strtotime($start[$i]) < strtotime($start_date . " 06:00")) {
$interval_high = strtotime($end[$i]) - strtotime($start[$i]); //needs further things
$amount_high += ceil($interval_high / 1800) / 2;
} elseif (strtotime($start[$i]) < strtotime($start_date . " 22:00") && strtotime($end[$i]) > strtotime($start_date . " 22:00")) {
$interval_high = strtotime($end[$i]) - strtotime($start_date . " 22:00");
$amount_high += ceil($interval_high / 1800) / 2;
} else {
$interval_low = strtotime($end[$i]) - strtotime($start[$i]);
$amount_low += ceil($interval_low / 1800) / 2;
}
}
echo $amount_low;
echo "\n$amount_high";
?>
Would this work for you?
$start = strtotime('2017-07-16 20:00');
$end = strtotime('2017-07-16 23:30');
$interval = $end - $start;
$hours = floor($interval / 1800)/2;
echo($hours);
This will display the total hours (in 0,5 increments) between the two dates (rounding down, so if it's 55 minutes, it's 0,5 hours; replace 'floor' with 'ceil' for the opposite).
I believe a part of your solution is found here from Aillyn
You can convert them to timestamps and go from there:
$hourdiff = round((strtotime($time1) - strtotime($time2))/3600, 1);
Dividing by 3600 because there are 3600 seconds in one hour and using round()
to avoid having a lot of decimal places.
$hourdiff = round((strtotime($time1) - strtotime($time2))/3600, 1);
This will give you a rounded hour difference between the two times. You could do something similar, just apply it for each interval for which ever month and adjust your math. There's not really going to be a single PHP function you can call to solve this.
Related
I want to know how do I use php to ask if time is bigger than
08:30
and lower than
21:15
if I use :
<?php
if ( (date("H")>8&&date("i")>30) && (date("H")<21&&date("i")<25) ) {
echo 'This website is closed from 08:30 - 21:25. Sorry for the Inconvenience.';
exit;
}
?>
This is not an accurate way to say that because even if time is bigger than 8 and lower than 21 there is a minute validation here...
You could get the date/time and strip of the date part. That time can be compared to other time values. In the code below, I calculate the values in seconds from midnight for the current time, 8:30 and 21:15, and then the if becomes quite simple:
define('SecondsPerDay', 86400);
define('SecondsPerHour', 3600);
define('SecondsPerMinute', 60);
$time = time () % SecondsPerDay;
$from = 8 * SecondsPerHour + 30 * SecondsPerMinute;
$to = 21 * SecondsPerHour + 15 * SecondsPerMinute;
if ($time >= $from && $time < $to) {
echo 'This website is closed from 08:30 - 21:25. Sorry for the Inconvenience.';
exit;
}
$startTime = '08:30';
$endTime = '21:15';
$time = new DateTime($startTime);
$time1 = date_format($time, 'H:i');
$time = new DateTime($endTime);
$time2 = date_format($time, 'H:i');
"Today is " . $current =date("H:i") . "<br>";
if ($current > $time1 && $current < $time2)
{
echo 'This website is closed from 08:30 - 21:25. Sorry for the Inconvenience.';
}else{
echo "It's open";
}
REFERENCE
Please take a look at the following code:
$parts_count = 3;
$diff = strtotime('2013-11-30 00:00:00') - time();
$diff = $diff / $parts_count;
for ($i = 0; $i < $parts_count; $i++) {
echo date('Y-m-d H:m:s', time() + $diff * ($i + 1) );
}
I am trying to divide the difference between the current time and a deadline (2013-11-30 00:00:00) into 3 equal parts.
The result I get is more than interesting though. It is:
2013-11-16 23:11:36
2013-11-23 11:11:48
2013-11-30 00:11:00
As you see, the latest deadline is 11 minutes past the original deadline, which is very weird. Do you have an idea why this happens?
Misspelling in format, should be:
echo date('Y-m-d H:i:s', time() + $diff * ($i + 1) );
So here is what I need to do:
Get time from database (don't worry about the database stuff for the moment)
Countdown time in days, hours and minutes
When countdown has reached 0, add 7 days to countdown along with adding 1 to an episode count
repeat multiple times until episode count reaches certain number (set by database, again don't worry to much about the database stuff at the moment) then stop countdown and just echo Aired
Basically its going to countdown to the next episode of a TV show's airing time and show what episode number is next, this will carry on until all the episodes have aired.
Here is what I have currently, it works to a degree but will only +7 days/++episode once, after that the countdown will go into negatives. I've tried while loops and some other things but I haven't had too much luck.
$date = "February 12, 2013 5:06 PM";
$date = strtotime($date);
$remaining = $date - time();
$episode = 0;
if ($remaining < 0) {
++$episode;
$remaining = strtotime("+7 day", $date) -time();
}
$days_remaining = floor($remaining / 86400);
$hours_remaining = floor(($remaining % 86400) / 3600);
$mins_remaining = floor(($remaining % 86400 % 3600) / 60);
if ($episode == 3){
echo "Aired";
} else {
echo "$days_remaining:$hours_remaining:$mins_remaining Ep $episode";
}
Any advice is really appreciated, thanks!
Of course it will go to negative.
After $remaining reaches 0, another 7 days are added to it.
if ($remaining < 0) { // remaining: less than 0 days
++$episode; // episode becomes 1
$remaining = strtotime("+7 day", $date) -time(); // remaining: less than 7 days
}
However, after another 7 days, $remaining is still negative and only 7 days are added to it. Since you haven't saved $episode in a database, it is still 0 according to the code.
$episode = 0; // $episode starts at 0 according to the code
if ($remaining < 0) { // remaining: less than -7 days
++$episode; // episode becomes 1
So it continues to count negative and give you $episode == 1.
You should do this instead:
$date = strtotime("February 12, 2013 5:06 PM");
for ($i = 0; $i < 3; $i++) {
$episodes[$i+1] = strtotime("+". 7*$i ." day", $date);
$remainings[$i+1] = $episodes[$i+1] - time();
}
foreach ($remainings as $key => $remaining) {
if ($remaining > 0) {
$episode = $key;
$days_remaining = floor($remaining / 86400);
$hours_remaining = floor(($remaining % 86400) / 3600);
$mins_remaining = floor(($remaining % 86400 % 3600) / 60);
break;
}
}
if (!isset($episode)){
echo "Aired";
} else {
echo "$days_remaining:$hours_remaining:$mins_remaining Ep $episode";
}
How do I get the exact dates of the last 7 days including today in a custom format (dd/mm)?
In the resulting array I would like to get something like (dates are examples only):
1=>11/2 (today minus 7 days)
2=>12/2 (today minus 6 days)
...
7=>17/2 (today)
function getLastNDays($days, $format = 'd/m'){
$m = date("m"); $de= date("d"); $y= date("Y");
$dateArray = array();
for($i=0; $i<=$days-1; $i++){
$dateArray[] = '"' . date($format, mktime(0,0,0,$m,($de-$i),$y)) . '"';
}
return array_reverse($dateArray);
}
Usage:
$arr = getLastNDays(7);
or
$arr = getLastNDays(7, 'd/m/Y');
You can combine the 2 functions date() and strtotime(). for example:
echo date("Y-m-d", strtotime("7 days ago"));
Try:
for ($i=0; $i<7; $i++)
{
echo date("d/m", strtotime($i." days ago")).'<br />';
}
You should be able to work out how to get them in the correct order and into an array :)
Hope that helps
time() gives you the current timestamp.
86400 seconds are one day (60 * 60 * 24).
date() gives you a custom date string.
for ($iDay = 6; $iDay >= 0; $iDay--) {
$aDays[7 - $iDay] = date('d/m', time() - $iDay * 86400);
}
Also see this example.
If you don't want the leading zeros, use 'j/n' as custom date format parameter:
for ($iDay = 6; $iDay >= 0; $iDay--) {
$aDays[7 - $iDay] = date('j/n', time() - $iDay * 86400);
}
Also see this updated example.
=== UPDATE ===
#Dagon's idea to use strtotime() to get the timestamp is great. Here the better solution:
for ($iDay = 6; $iDay >= 0; $iDay--) {
$aDays[7 - $iDay] = date('j/n', strtotime("-" . $iDay . " day"));
}
And an example.
I have this function that gives me a set of options in a select input.
The options give me times with 5 minute interval.
The problem is when the time is like 23:45, the options will start from 00:10 and loops based on the $j variable.
This is what I want to do in words:
Give me a list of options in 5 minutes interval from $open_time till $close_time.
If the current Time ($timeNow) is greater than the $open_time, set the $open_time to the $timeNow to be shown as first option.
Do this loop only until the $close_time.
I hope this is clear.
Appreciate your help :)
Here is the code:
function selectTimesofDay(){
$output = "";
$now = date('G:i ', time()); // time now
$timeNow = strtotime($now); // strtotime now
$next_five = ceil($timeNow / 300) * 300; // get next 5 minute
// time now rounded to next 10 minute
$round5minNow = date('G:i', strtotime('+15 minutes',$next_five));
$open_time = strtotime('17:00');
$close_time = strtotime('23:59');
// in the middle of working hours, time sets to current
if($timeNow >= $open_time && $timeNow < $close_time){
$open_time = strtotime($round5minNow);
}
$time_diff = round(($close_time - $open_time)/60) ;
if(date('l') == 'Friday'){
$j = ($time_diff/5)+11; // working hours extended untill 1:00 AM
} else{
$j = ($time_diff/5)-1; // working hours untill 12:00 AM
}
for($i = 0; $i <= $j; $i++){
$b = $i*5;
$data = date('l')." - ".date("H:i", strtotime('+'.$b.' minutes', $open_time));
$output .= "<option value=\"{$data}\">";
$output .= $data;
$output .= "</option>";
}
return $output;
}
What you really need is:
function selectTimesOfDay() {
$open_time = strtotime("17:00");
$close_time = strtotime("23:59");
$now = time();
$output = "";
for( $i=$open_time; $i<$close_time; $i+=300) {
if( $i < $now) continue;
$output .= "<option>".date("l - H:i",$i)."</option>";
}
return $output;
}
So what this does is run a loop checking every five-minute interval between opening and closing. Skip it if it is before the curent time, and otherwise add an option.
It's much more efficient than what you were trying to do, and probably easier to understand too.
You can even put this after the loop:
if( $output == "") return "<option disabled>Sorry, we're closed for today</option>";
Also, notice how I left out the value attribute all the time. That's because in the absence of a value, the option's text is used as a value. Thus this solution avoids needless duplication.
Consider taking the hard-coded open and close times out of the function body. The goal with functions is to write code that you can reuse, so if your hours change then you don't have to change with your function, but rather the arguments that are passed to it.
// sample usage: print '<select>'.selectTimesofDay('17:00', '23:59').'</select>';
function selectTimesofDay($start=false, $end=false, $interval='5 minutes'){
$interval = DateInterval::createFromDateString($interval);
$rounding_interval = $interval->i * 60;
$date = new DateTime(
date('Y-m-d H:i', round(strtotime($start) / $rounding_interval) * $rounding_interval)
);
$end = new DateTime(
date('Y-m-d H:i', round(strtotime($end) / $rounding_interval) * $rounding_interval)
);
$opts = array();
while ($date < $end) {
if ($date->getTimestamp() < time()) {
$date->add($interval);
continue;
}
$data = $date->format('l').' - '.$date->format('H:i');
//$opts[] = '<option value="'.$date->getTimestamp().'">'.$data.'</option>'; // < -- pass the timestamp instead of a string?
$opts[] = '<option>'.$data.'</option>';
$date->add($interval);
}
return count($opts) < 1 ?
'<option value="-1">- closed -</option>' :
implode("\n", $opts);
}
Documentation
PHP's DateTime object - http://www.php.net/manual/en/class.datetime.php
PHP's DateInterval object - http://www.php.net/manual/en/dateinterval.format.php
PHP functions - http://www.php.net/manual/en/functions.user-defined.php
PHP function tutorial - http://www.tizag.com/phpT/phpfunctions.php