php carbon check if now is between two times (10pm-8am) - php

$start = '22:00:00';
$end = '08:00:00';
$now = Carbon::now('UTC');
How can I check if the time of $now is within the timerange?

There are several ways to achieve that by using Carbon. One of the easiest ways is using createFromTimeString and between methods:
$now = Carbon::now();
$start = Carbon::createFromTimeString('22:00');
$end = Carbon::createFromTimeString('08:00')->addDay();
if ($now->between($start, $end)) {
// ¯\_(ツ)_/¯
}

Try this:
$time = Carbon::now();
$morning = Carbon::create($time->year, $time->month, $time->day, 8, 0, 0); //set time to 08:00
$evening = Carbon::create($time->year, $time->month, $time->day, 18, 0, 0); //set time to 18:00
if($time->between($morning, $evening, true)) {
//current time is between morning and evening
} else {
//current time is earlier than morning or later than evening
}
The true in $time->between($morning, $evening, true) checks whether the $time is between and including $morning and $evening. If you write false instead it checks just if it is between the two times but not including.
Actually, you could leave true away because it is set by default and not needed.
Check here for more information on how to compare dates and times with Carbon.

$start = '22:00:00';
$end = '08:00:00';
$now = Carbon::now('UTC');
$time = $now->format('H:i:s');
if ($time >= $start && $time <= $end) {
...
}
Should do it, but doesn't take date into consideration

You can reverse check algorithm.
<?php
$pushChannel = "general";
$now = Carbon::now();
$start = Carbon::createFromTime(8, 0);
$end = Carbon::createFromTime(22, 0);
if (!$now->between($start, $end)) {
$pushChannel = "silent";

$restrictStartTime = Carbon::createFromTime(22, 0, 0); //carbon inbuild function which will create todays date with the given time
$restrictEndTime = Carbon::createFromTime(8, 0, 0)->addDays(1); //this will create tomorrows date with the given time
$now = Carbon::now();
if($now->gt($restrictStartTime) && $now->lt($restrictEndTime)) {
.....
}

Please Try below code,
$start = '22:00:00';
$end = '08:00:00';
$now = Carbon::now('UTC');
$nowTime = $now->hour.':'.$now->minute.':'.$now->second;
if(strtotime($nowTime) > strtotime($start) && strtotime($nowTime) < strtotime($end) ) {
echo 'YES';
} else {
echo 'NO';
}

What Chris is trying to point out is if the endtime crosses over midnight then you must account for that.
This is not the cleanest way to do it but here is a method that seems to work.
private function isNowBetweenTimes($timezone, $startDateTime, $endDateTime) {
$curTimeLocal = Carbon::now($timezone);
$startTime = $curTimeLocal->copy();
$startTime->hour = $startDateTime->hour;
$startTime->minute = $startDateTime->minute;
$endTime = $curTimeLocal->copy();
$endTime->hour = $endDateTime->hour;
$endTime->minute = $endDateTime->minute;
if ($endTime->lessThan($startTime))
$endTime->addDay();
return ($curTimeLocal->isBetween($startTime, $endTime));
}
This example only cares about the hour and minutes and not the seconds but you can easily copy that as well. The key to this is comparing start and end time before comparing them to the current time and add a day to end time if end time is less than start time.

For complete solution which supports all start and end time range you can use bitwise XOR.
/*
* must using hours in 24 hours format e.g. set 0 for 12 pm, 6 for 6 am and 13 for 1 pm
*/
private $startTime = '0';
private $endTime = '6';
$currentHour = \Carbon\Carbon::now()->hour;
$start = $this->startTime > $this->endTime ? !($this->startTime <= $currentHour) : $this->startTime <= $currentHour;
$end = $currentHour < $this->endTime;
if (!($start ^ $end)) {
//Do stuff here if you want exactly between start and end time
}

an updated version of #AliN11's answer taking into account ranges accross two days or in the same day
$now = now();
$start = Carbon::createFromTimeString('22:00');
$end = Carbon::createFromTimeString('08:00');
if ($start > $end) {
$end = $end->addDay();
}
if ($now->between($start, $end)||$now->addDay()->between($start, $end)) {
//add statements
}

<?php
$now = date("H");
if ($now < "20") {
echo "Have a good day!";
}

Try this :
$start = 22; //Eg. start hour
$end = 08; //Eg. end hour
$now = Carbon::now('UTC');
if( $start < $now->hour && $now->hour < $end){
// Do something
}

#AliN11's (currently top) answer is good, but doesn't work as one would immediately expect, after midnight it just breaks, as raised in the comments by #Sasha
The solution is to reverse the logic, and check if the time is not between the inverse hours.
Here is an alternative that works as one would expect:
$now = Carbon::now();
$start = Carbon::createFromTimeString('08:00');
$end = Carbon::createFromTimeString('22:00');
if (! $now->between($start, $end)) {
// We're all good
}

Yes, the midnight plays a vital role in time duration. We can find now() being the given time range as follows:
$now = Carbon::now();
$start = Carbon::createFromTime('22', '00');
$end = Carbon::createFromTime('08', '00');
if ($start->gt($end)) {
if ($now->gte($start)) {
$end->addDay();
} elseif ($now->lte($end)) {
$start->subDay();
} else {
return false;
}
}
return $now->between($start, $end);

Related

Get minutes from two timestamps, which are on a Sunday in PHP

I have two timestamps, which possibly can be any date and time. I want to get all minutes, which were on Sunday.
For a better understanding: The start and and end timestamp represent a date and time where an employee starts his work and finish his work. I want to get the minutes in sum, which the employee worked on a Sunday.
Here is my code:
function get_sunday_hours_from_timestamps($startTimestamp, $endTimestamp) {
$start = new DateTime();
$start->setTimestamp($startTimestamp);
$end = new DateTime();
$end->setTimestamp($endTimestamp);
$workedMinutes = 0;
$current = clone $start;
while ($current <= $end) {
$next = clone $current;
$next->modify('next day');
if ($current->format('w') == 0) {
$dayStart = ($current < $start) ? $start : $current;
$dayEnd = ($next > $end) ? $end : $next;
$diff = $dayEnd->diff($dayStart);
$minutes = $diff->days * 1440 + $diff->h * 60 + $diff->i;
$workedMinutes += $minutes;
}
$current = $next;
}
return $workedMinutes / 60;
// return $workedMinutes;
}
Thank you for your input. I was able to solve the problem. Hope this helps anybody else.
function get_sunday_hours_from_timestamps($startTimestamp, $endTimestamp) {
$totalMinutes = 0;
$startDay = strtotime("midnight", $startTimestamp);
$endDay = strtotime("tomorrow", $endTimestamp) - 1;
for ($currentDay = $startDay; $currentDay <= $endDay; $currentDay = strtotime("+1 day", $currentDay)) {
if (date("l", $currentDay) == "Sunday") {
$start = max($startTimestamp, $currentDay);
$end = min($endTimestamp, strtotime("tomorrow", $currentDay) - 1);
$totalMinutes += ($end - $start) / 60;
}
}
return round($totalMinutes / 15) * 0.25;
}
Warning: The solution below is highly inefficient and extremely slow, especially for large time periods as input. It only serves to illustrate a naive approach in an easily readable form. You can use this as a starting point, but use it wisely!
A very naive approach to your problem (count sunday minutes in a given time period) could be: Iterate over every minute in you period, check if that minute is on a sunday and count those minutes.
In PHP that could look like this:
function isSunday(DateTimeInterface $dateTime) {
return $dateTime->format('w') == 0;
}
function countSundayMinutes(DateTime $start, DateTime $end): int
{
if ($start >= $end) {
throw new LogicException('end must be > start!');
}
$sundayMinutes = 0;
$current = clone $start;
while ($current < $end) {
if (isSunday($current)) {
$sundayMinutes++;
}
$current = $current->add(DateInterval::createFromDateString('1 minute'));
}
return $sundayMinutes;
}
echo countSundayMinutes(new DateTime('2023-01-02 00:00'), new DateTime('2023-01-03 00:00')), PHP_EOL; // 0: total 24h, not on sunday
echo countSundayMinutes(new DateTime('2023-01-01 12:00'), new DateTime('2023-01-01 13:00')), PHP_EOL; // 60: total 60 minutes, thereof 60 on sunday
echo countSundayMinutes(new DateTime('2022-12-31 23:00'), new DateTime('2023-01-01 01:00')), PHP_EOL; // 60: total 12 minutes, thereof 60 on sunday
echo countSundayMinutes(new DateTime('2022-12-31 00:00'), new DateTime('2023-01-03 00:00')), PHP_EOL; // 1440: total 72h, thereof 24h (1440 minutes) on sunday
But i'm sure you'll be able to add many optimizations to that algorithm, e.g. you could check first if the given period includes any sundays at all...

How to set fix time variables in php?

I want to set a fix time variables in php for my if and else condition.
For example:
$startTime = '08:00:00';
$endTime = '16:00:00';
$totalhrs = $endTime - $startTime;
echo $totalhrs;
Anyone know how to declare the time in PHP?
Thanks for the help
$startTime = strtotime('08:00:00');
$endTime = strtotime('16:00:00');
$totalhrs = ($endTime - $startTime) / 3600;
echo $totalhrs;
you can use datetime object for this case
$startTime = new DateTime('08:00:00');
$endTime = new DateTime('16:00:00');
$totalhrs = $startTime->diff($endTime)->h;
You can try the below function to check timestamps. If you don't pass it a second parameter, it will evaluate if the first time has passed the CURRENT time, otherwise it will compare the first time against the second.
Function timeHasPassed($Time, $Time2 = 0) {
If ($Time2 != 0) {
$Now = new DateTime($Time2);
} Else {
$Now = new DateTime();
}
$Then = new DateTime($Time);
If ($Now > $Then) {
Return TRUE;
} Else {
Return FALSE;
/*
You can also use the below code to print out how long is left until the timestamp has passed. Keep in mind, this will return TRUE if tested as a boolean so maybe consider returning a different datatype instead of TRUE if you decide to go this route.
$Time = new DateTime($Time);
$Now = new DateTime();
$Remainder = $Time->diff($Now);
$Remainder = $Remainder->format("%h hours, %i minutes, and %s seconds!");
return $Remainder;
*/
}
}

PHP timestamp and dates issue

So I have a piece of code on a certain page of my site that does things with timestamps. Pretty much what it does is there is a UNIX timestamp that is placed in the database from each individual Purchase Order. Once a certain amount of time has passed and nothing has been done to that Purchase Order then an indication will begin flashing on the page with the amount of hours that is past due. Once someone takes action then the flashing indication goes away.
Now, everything is working perfectly fine. The issue I am having is that the indicator should only take Monday thru Friday into account. Not the weekends. Also, I've set the hours from 9am to 5pm est but the code seems to 100% skip all these restrictions and just takes all days and times into consideration.
I've placed the code below and as you can see I've set the restrictions of days and time but it seems to be voided somehow. Any help would be much appreciated with this issue.
$current_stardate = time();
$past_stardate = $stardate['time_stamp'];
$placer = ($current_stardate - $past_stardate) / 3600;
$from = date("Y-m-d H:i:s", $current_stardate);
$to = date("Y-m-d H:i:s", $past_stardate);
define('DAY_WORK', 28800); // 9 * 60 * 60
define('HOUR_START_DAY', '09:00:00');
define('HOUR_END_DAY', '17:00:00');
$date_begin = $to;
$date_end = $from;
$d1 = new DateTime($date_begin);
$d2 = new DateTime($date_end);
$period_start = new DateTime($d1->format('Y-m-d 00:00:00'));
$period_end = new DateTime($d2->format('Y-m-d 23:59:59'));
$interval = new DateInterval('P1D');
$period = new DatePeriod($period_start, $interval, $period_end);
$worked_time = 0;
$nb = 0;
foreach($period as $date){
$week_day = $date->format('w'); // 0 (for Sunday) through 6 (for Saturday)
if (!in_array($week_day,array(1, 5)))
{
if ($date->format('Y-m-d') == $d1->format('Y-m-d'))
{
$end_of_day_format = $date->format('Y-m-d '.HOUR_END_DAY);
$d1_format = $d1->format('Y-m-d H:i:s');
$end_of_day = new DateTime($end_of_day_format);
$diff = $end_of_day->diff($d1)->format("%H:%I:%S");
$diff = split(':', $diff);
$diff = $diff[0]*3600 + $diff[1]*60 + $diff[0];
$worked_time += $diff;
}
else if ($date->format('Y-m-d') == $d2->format('Y-m-d'))
{
$start_of_day = new DateTime($date->format('Y-m-d '.HOUR_START_DAY));
$d2_format = $d2->format('Y-m-d H:i:s');
$end_of_day = new DateTime($end_of_day_format);
$diff = $start_of_day->diff($d2)->format('%H:%I:%S');
$diff = split(':', $diff);
$diff = $diff[0]*3600 + $diff[1]*60 + $diff[0];
$worked_time += $diff;
}
else
{
$worked_time += DAY_WORK;
}
}
if ($nb> 10)
die("die ".$nb);
}
$the_work = $worked_time/60/60;
$genesis_stardate = strtotime($stardate['date_purchased']);
if($past_stardate == NULL)
{
$the_work = NULL;
$future_days = NULL;
}
else
{
$future_days = ($current_stardate - $past_stardate) / 3600;
}
$date is not defined. Try to define it, and the problem should be solved.

PHP check if time falls within range, questioning common solution

I have to check if the current daytime falls in a specific range. I looked up the internet and found several similar solutions like this one:
$now = date("His");//or date("H:i:s")
$start = '130000';//or '13:00:00'
$end = '170000';//or '17:00:00'
if($now >= $start && $now <= $end){
echo "Time in between";
}
else{
echo "Time outside constraints";
}
If both conditions have to be true, how can this bis achieved when we assume that $start is 06:00:00 and $end is 02:00:00.
If we make the assumption that it is 01:00:00, in this case the first condition can't be true.
Has anybody an idea to handle this problem differently?
Thanks!
Naturally, you'd have to account for date in your comparisons.
<?php
$start = strtotime('2014-11-17 06:00:00');
$end = strtotime('2014-11-18 02:00:00');
if(time() >= $start && time() <= $end) {
// ok
} else {
// not ok
}
If you need to check whether or not the time frame rolls over midnight
function isWithinTimeRange($start, $end){
$now = date("His");
// time frame rolls over midnight
if($start > $end) {
// if current time is past start time or before end time
if($now >= $start || $now < $end){
return true;
}
}
// else time frame is within same day check if we are between start and end
else if ($now >= $start && $now <= $end) {
return true;
}
return false;
}
You can then get whether or not you are within that time frame by
echo isWithinTimeRange(130000, 170000);
date_default_timezone_set("Asia/Colombo");
$nowDate = date("Y-m-d h:i:sa");
//echo '<br>' . $nowDate;
$start = '21:39:35';
$end = '25:39:35';
$time = date("H:i:s", strtotime($nowDate));
$this->isWithInTime($start, $end, $time);
function isWithInTime($start,$end,$time) {
if (($time >= $start )&& ($time <= $end)) {
// echo 'OK';
return TRUE;
} else {
//echo 'Not OK';
return FALSE;
}
}
Cannot comment due to low reputation, but #DOfficial answer is great but be aware of inconsistency in comparision.
Original
// if current time is past start time or before end time
if($now >= $start || $now < $end){
Should be imho
// if current time is past start time or before end time
if($now >= $start || $now <= $end){

Calculate what the date will be based on startdate and value using PHP skip weekends

I have a startdate, let's say this is $startDate = 2012-08-01; and I have a variable that stores an INT value, lets say this is $value = 10;
I would like to calculate what the date would be from startdate + 10 days and skip weekends.
Using the above values the result would be 2012-08-15
How would this be done?
This is far from efficient, but who cares about that right when it is readable? :)
<?php
function calculateNextDate($startDate, $days)
{
$dateTime = new DateTime($startDate);
while($days) {
$dateTime->add(new DateInterval('P1D'));
if ($dateTime->format('N') < 6) {
$days--;
}
}
return $dateTime->format('Y-m-d');
}
echo calculateNextDate('2012-08-01', 10); // return 2012-08-15
DEMO
What happens should be pretty easy to follow. First we create a new DateTime object using the date provided by the user. After that we are looping through the days we want to add to the date. When we hit a day in the weekend we don't subtract a day from the days we want to add to the date.
you can use php's strtotime function to + n days/hours etc..,
and for excluding weekends have a look here:
32 hours ago excluding weekends with php
Try this
<?php
function businessdays($begin, $end) {
$rbegin = is_string($begin) ? strtotime(strval($begin)) : $begin;
$rend = is_string($end) ? strtotime(strval($end)) : $end;
if ($rbegin < 0 || $rend < 0)
return 0;
$begin = workday($rbegin, TRUE);
$end = workday($rend, FALSE);
if ($end < $begin) {
$end = $begin;
$begin = $end;
}
$difftime = $end - $begin;
$diffdays = floor($difftime / (24 * 60 * 60)) + 1;
if ($diffdays < 7) {
$abegin = getdate($rbegin);
$aend = getdate($rend);
if ($diffdays == 1 && ($astart['wday'] == 0 || $astart['wday'] == 6) && ($aend['wday'] == 0 || $aend['wday'] == 6))
return 0;
$abegin = getdate($begin);
$aend = getdate($end);
$weekends = ($aend['wday'] < $abegin['wday']) ? 1 : 0;
} else
$weekends = floor($diffdays / 7);
return $diffdays - ($weekends * 2);
}
function workday($date, $begindate = TRUE) {
$adate = getdate($date);
$day = 24 * 60 * 60;
if ($adate['wday'] == 0) // Sunday
$date += $begindate ? $day : -($day * 2);
return $date;
}
$def_date="";//define your date here
$addDay='5 days';//no of previous days
date_add($date, date_interval_create_from_date_string($addDay));
echo businessdays($date, $def_date); //date prior to another date
?>
Modified from PHP.net
if you just want to add up a date +10, you may wanna consider this:
date("Y-m-d", strtotime("+10 days"));

Categories