Compare current hour with period of time - php

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";
}

Related

Calculating working hours time difference in PHP

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

PHP - Counting Leap Days in Date Range

I am trying to count the number of leap days within a date range.
This is what I have so far (adopted code from here)
<?php
$date_from = strtotime('2019-06-01');
$date_to = strtotime('2021-05-30');
$leapday_count = 0;
for($year=$date_from; $year<=$date_to; $year=strtotime('next year', $year)) {
if (date('L', $year)) {
$leapday_count++;
}
}
echo $leapday_count;
?>
Here is what I need help with:
The above code does only look at the years of the start and end date. For example it does not take into consideration if the start date is after Feb 29th. How can I make sure that it really takes the entire dates into consideration and not only the years of the dates?
Example expected result: 0 leap days between 2020-03-01 2024-02-28
Example expected result: 2 leap days between 2020-02-28 2024-03-01
Thanks in advance!
Stop doing date maths. It's hard.
Use datetime and diff
http://php.net/manual/en/datetime.diff.php
Example there
$datetime1 = new DateTime('2009-10-11');
$datetime2 = new DateTime('2009-10-13');
$interval = $datetime1->diff($datetime2);
echo $interval->format('%R%a days');
to exactly answer the question.
$start = new DateTime('2020-03-01');
$end = new DateTime('2024-02-28');
$interval = ("last day of feb next year");
$current = clone $start;
$leapYears = 0;
while ($current->modify("last day of feb") && $current <= $end) {
if ($current->format('d') == 29 && $current > $start) {
$leapYears++;
}
$current->modify("+1 year");
}

Compare 2 time which is greater without date in PHP

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 = ...

Php creating hours except lunch hours

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);
}

PHP If an Hour Is Between Two Other Hours

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';

Categories