I need to work out if the current hour is between two other times. For example to check if the time is between 07:00 and 10:00 I could use:
$currentTime = new DateTime('09:00');
$startTime = new DateTime('07:00');
$endTime = new DateTime('10:00');
if ($currentTime->format('H:i') >= $startTime->format('H:i') && $currentTime->format('H:i') <= $endTime->format('H:i')) {
// Do something
}
The problem I have is what happens if the time is 01:00 and I want to check if it's between 22:00 and 07:00. I'm not bothered that that it is another day, just if it falls between those two hours on a 24hr clock. Example 01:00 is between 22:00 and 07:00
22:00, 23:00, 00:00, 01:00, 02:00... 07:00
What I'm trying to achieve in the end is different prices can be set for a service between different times. So I currently loop through each hour working out what price bracket that hour falls into and the changing the price accordingly. If anyone has a more elegant solution for the problem I would be grateful to learn.
UPDATE:
Say I have a rule that says between 10pm and 7am I want to charge double. I loop through each hour from the start time to the end time and check if each hour falls between 22:00 (10pm) and 07:00 (7am) and if so it should be charged double. I want to avoid having to take in to account the date.
<?php
$currentTime = strtotime('1:00');
$startTime = strtotime('22:00');
$endTime = strtotime('7:00');
if (
(
$startTime < $endTime &&
$currentTime >= $startTime &&
$currentTime <= $endTime
) ||
(
$startTime > $endTime && (
$currentTime >= $startTime ||
$currentTime <= $endTime
)
)
) {
echo 'open';
} else {
echo 'clse';
}
No need to use DateTime::format() for your comparisons. DateTime objects are already comparable.
To handle working with time periods that span midnight you will need to change the date so you have an accurate reflection of the actual date.
$currentTime = (new DateTime('01:00'))->modify('+1 day');
$startTime = new DateTime('22:00');
$endTime = (new DateTime('07:00'))->modify('+1 day');
if ($currentTime >= $startTime && $currentTime <= $endTime) {
// Do something
}
I found another way starting from the first and more popular solution that has the problem that doesn't work for me.
I have to write something between 10:00 pm and 06:00 am and the comparison does not work because when i pass midnight the endTime was always > of the start time.
so if i don't mind about the day i solved in this way:
$currentTime = new DateTime();
$startTime = new DateTime('22:00');
$endTime = (new DateTime('06:00'))->modify('+1 day');
if ($currentTime->format("a") == "am") {
// echo "It's a new day <br />";
$currentTime = $currentTime->modify('+1 day');
}
if ($currentTime >= $startTime && $currentTime <= $endTime) {
echo "hello";
}
//get current DateTime
$date = new DateTime('now');
$currentHour = 0;
$currentMinutes = 0;
foreach ($date as $item=>$value ) {
if($item=="date"){
$p = explode(" ",$value)[1];
$hour = explode(":",$p);
$currentHour = $hour[0];
$currentMinutes = $hour[1];
}
}
$returnVO["success"] = ((int)$currentHour<12 || ((int)$currentHour>=22 && (int)$currentMinutes > 0) ) ? false : true;
$hour = (int)date('H');
echo ($hour > 7 && $hour < 22) ? 'Open' : 'Close';
$hour = (int)date('H');
echo ($hour <= 7 || $hour >= 22) ? 'Close':'Open';
Related
I wanted to calculate the number of hours between the encoded date and completion date. As of now I can compute the time difference between the two datetimes excluding the Saturdays and Sundays. My problem is I need to exclude the lunch breaks (12:00 am to 1:00 pm) and holidays.
Here is my code:
<?php
function business_hours($start, $end){
$startDate = new DateTime($start);
$endDate = new DateTime($end);
$periodInterval = new DateInterval( "PT1H" );
$period = new DatePeriod( $startDate, $periodInterval, $endDate );
$count = 0;
$holidays = [
"Human Rights Day" => new DateTime(date('Y') . '-03-21'),
"Good Friday" => new DateTime(date('Y') . '-03-30'),
"Family Day" => new DateTime(date('Y') . '-04-02'),
"Freedom Day" => new DateTime(date('Y') . '-04-27'),
"Labour Day" => new DateTime(date('Y') . '-05-01'),
"Youth Day" => new DateTime(date('Y') . '-06-16'),
"National Women's Day" => new DateTime(date('Y') . '-08-09'),
"Heritage Day" => new DateTime(date('Y') . '-09-24'),
"Day of Reconciliation" => new DateTime(date('Y') . '-12-16'),
];
foreach($period as $date){
$startofday = clone $date;
$startofday->setTime(8,00);
$endofday = clone $date;
$endofday->setTime(17,00);
if($date > $startofday && $date <= $endofday && !in_array($date->format('l'), array('Sunday','Saturday'))){
$count++;
}
}
echo $count;
}
$start = '2020-02-14 08:00:00';
$end = '2020-02-17 08:00:00';
$go = business_hours($start,$end);
//output 9 hours
?>
As per my code, I set the working hours from 8:00 to 17:00 and then excluded the Saturdays and Sundays. As per my example the output will be 9 (including the lunch break). How can I exclude the lunch break and holidays?
Update
The completion time can be more than 1 day. For example, the start date/time is 2020-02-14 08:00:00 and the completion time is 2020-02-19 08:00:00 the output is 27 hours. The calculation should exclude the lunch breaks of each day that have 12:00am to 1:00pm and holidays in between.
Update
I added an array of holidays, how can I exclude these holidays?
Since you're using a static/defined lunch break, you can use the following logic:
If $startDate is a weekday, and before 12:00, that's the start date for lunch calculation; otherwise it's the next weekday.
If the $endDate is a weekday, and after 13:00, that's the end date for lunch calculation; otherwise, it's the previous weekday
Actual number of lunch breaks equals the difference between those recalculated dates, at one hour each.
The following is pseudocode:
if(!in_array($startDate->format('l'), array('Sunday','Saturday')) && ($startDate->format('g') < 12) {
$startForLunch = $startDate;
}
else {
$startForLunch = new DateTime($start, '+1 day');
while(in_array($startDate->format('l'), array('Sunday','Saturday'))){
$startForLunch->add('1 day');
}
}
if(!in_array($endDate->format('l'), array('Sunday','Saturday')) && ($endDate->format('g') > 13) {
$endForLunch = $end;
}
else {
$endForLunch = new DateTime($endDate, '-1 day');
while(in_array($endDate->format('l'), array('Sunday','Saturday'))){
$endForLunch->add('-1 day');
}
}
$lunchPeriods = $endForLunch - $startForLunch + 1;
how about try add some condition inside loop each day to skip some hours
($date->format('H') <= 12 || $date->format('H') > 13)
it will skip if hour above 12 to 13 (if you use 24 format hour)
if($date > $startofday && $date <= $endofday && !in_array($date->format('l'), array('Sunday','Saturday')) && ($date->format('H') <= 12 || $date->format('H') > 13)){
$count++;
}
UPDATE
okay if your "holydays" is cutom maybe be good to add some paramerter to your function to store list of your holydays
function business_hours($start, $end,$holyDays = null){
//another line
}
and check every loop of dates is in on holydays list or not
in_array($date->format('Y-m-d'), $holyDays)
you will get filter of break time and custom holyday
function business_hours($start, $end,$holyDays = null){
$startDate = new DateTime($start);
$endDate = new DateTime($end);
$periodInterval = new DateInterval( "PT1H" );
$period = new DatePeriod( $startDate, $periodInterval, $endDate );
$count = 0;
foreach($period as $date){
$startofday = clone $date;
$startofday->setTime(8,00);
$endofday = clone $date;
$endofday->setTime(17,00);
//just some var to use in conditional check
$notHolyday = true;
//now check the array of holyday and check if in range dates is same with holydays we have
if($holyDays != null && is_array($holyDays) && in_array($date->format('Y-m-d'), $holyDays)){
$notHolyday = false;
}
if($date > $startofday && $date <= $endofday && !in_array($date->format('l'), array('Sunday','Saturday')) && ($date->format('H') <= 12 || $date->format('H') > 13) && $notHolyday){
$count++;
}
}
echo $count;
}
$start = '2020-02-14 08:00:00';
$end = '2020-02-19 08:00:00';
$holyDays = array('2020-02-17','2020-02-18');
$count = business_hours($start,$end,$holyDays);
echo $count;
i hope this is want you want
I am trying to get the result that which time is greater. I mean there is no date only time.
$open_time = date("g:i A", strtotime($restaurant['open_time']));
$close_time = date("g:i A", strtotime($restaurant['close_time']));
$curren_time = date("h:i");
$restaurant['open_time'] and $restaurant['close_time'] is the result from database. It is coming in 24 hour format like 22:30, 10:20.
What i want exactly.
if(($current_time > $open_time) && ($current_time < $close_time)
{
echo "Opened";
}
else
{
echo "Closed";
}
If current_time is 2:00 AM and open_time is 11:00 AM then the result should echo Closed. And like this if current_time is 1:00 PM and closed_time is 11:00 PM then the result should echo Opened. Hope i explained well. Please ask if you have any doubt in my question.
You can solve thus using 24 hour format time also. But remember you can add date but virtually not from database. You can use to get the greater time
Set correct timezone and should work.
$restaurant = [
'open_time' => '11:00',
'close_time' => '22:00'
];
$timeZone = new DateTimeZone('Europe/Warsaw');
$now = new DateTime('now', $timeZone);
$open = DateTime::createFromFormat('H:i', $restaurant['open_time'], $timeZone);
$close = DateTime::createFromFormat('H:i', $restaurant['close_time'], $timeZone);
$working_now = ($now > $open && $now < $close);
if ($working_now) {
echo 'open';
} else {
echo 'closed';
}
You can play with it in sandbox - uncomment the test line to change current time.
If it's open through midnight you might need additional logic there:
if ($open > $close) {
if ($now > $close) {
$close->modify('+1 day');
} else {
$open->modify('-1 day');
}
}
$working_now = ...
I want to perform certain tasks in PHP between Monday 10:00am till Saturday 10:00am and I want to perform other tasks between Saturday 10:30am till Monday 10am. Every week.
I am sorry if that's a silly question. Any help would be highly appreciated.
if you are running a time triggered task run a cron job or if it is a user triggered like website and you want to change page according to day then use if else statement to select task.
you can get the time in weekday and hour:minute::second for if else selection using this
$d = new DateTime('Sunday,23:23:48 '); //set time day time format
echo $d->format('l , H:i:s ');
$date = new DateTime(); // get current datetime
echo $date->format('l , H:i:s '); //php get time in day time format
//output example Sunday , 23:23:48 Sunday , 23:34:47
$currentTime = time();
$time = date('H:i',$currentTime);
$date = date('h:i:s a', time());
$timestamp = strtotime($date);
$day = date('D', $timestamp);
if ( ( ($day == "Sat") && ($time < 11) ) || ($day == "Mon" && $time > 9) )
{
# weekday then truncate table
}
I'm creating an appointment system. Hours creating automatically 10 by 10 but I need to remove lunch hours these are 12:00 between 13:00 from 24 hour date time system.
$start=strtotime("08:30");
$end=strtotime("17:30");
$now=$start;
while($now <= $end){
echo '<option value="'.date("H:i",$now).':00">'.date("H:i",$now).'</option>';
$now = strtotime('+10 minutes',$now);
}
Just add lunch time:
$start=strtotime("08:30");
$end=strtotime("17:30");
$startLunch=strtotime("12:00");
$endLunch=strtotime("13:00");
$now = $start;
// and then you can use it in your while loop:
while($now <= $end){
if($now < $startLunch || $now > $endLunch)
{
echo '<option value="'.date("H:i",$now).':00">'.date("H:i",$now).'</option>';
}
$now = strtotime('+10 minutes',$now);
}
Try this out:
$start=strtotime("08:30");
$end=strtotime("17:30");
$lunch_start=strtotime("12:00");
$lunch_end=strtotime("13:00");
$now=$start;
while(($now <= $end) && ($now >= $lunch_start || $now <= $lunch_end)){
echo '<option value="'.date("H:i",$now).':00">'.date("H:i",$now).'</option>';$now = strtotime('+10 minutes',$now);
}
I want to compare if the current hour is between the interval 7 PM to 1 AM
for example I want to do
if(time() > strtotime('7PM') && time()< strtotime('1AM'))
{
echo "is between 7PM-1AM"
}
#deceze's comment above explains your problem. Here's an example that specifies 1AM the next day:
$now = new DateTime();
$start = new DateTime('7PM');
$finish = new DateTime('tomorrow 1AM');
if($now > $start && $now < $finish)
{
echo "is between 7PM-1AM";
}