I have two times like start_time and end_time and also having a time range like a start time and a end time. I want to check start_time and end_time are in the range of start time and end time or not. How to check that.
$start_time1 = 10:15 am; //! time table start time
$end_time1 = 12:30 pm; //! time table end time
$strattime2 = 10:00 am; //! time range - start time
$endtime2 = 1:00 pm; //! time range - end time
How to resolve this problem?
Just check the boundary of the range. The query must be started on or after the range and must be ended on or before the range ends. So
function check($queryStart, $queryEnd, $rangeStart, $rangeEnd) {
return ($queryStart >= $rangeStart && $queryEnd <= $rangeEnd);
}
If you want to check whether the query is overlapping the range or not, you should check whether the query ends before the range start or the query starts after the range end.
function overlap($queryStart, $queryEnd, $rangeStart, $rangeEnd) {
return !($queryEnd < $rangeStart || $queryStart > $rangeEnd);
}
you may convert all the times to DateTime() Objects and then check the difference like so:
<?php
function startStopTimeIsWithinRange($startTime='10:15', $stopTime='12:30') {
$dateStart = new DateTime('2016-10-30 ' . $startTime); //<== IGNORE, THE DATE. NOTICE THE TIME
$dateStop = new DateTime('2016-10-30 ' . $stopTime); //<== IGNORE, THE DATE. NOTICE THE TIME
$rangeStart = new DateTime('2016-10-30 10:00'); //<== IGNORE, THE DATE. NOTICE THE TIME
$rangeStop = new DateTime('2016-10-30 13:00'); //<== IGNORE, THE DATE. NOTICE THE TIME
if($dateStart >= $rangeStart && $rangeStop >= $dateStop){
return true;
}
return false;
}
var_dump( startStopTimeIsWithinRange('10:15', '12:30') ); //<== NOTICE THE COLON (:) AND NOT DOT (.)
Related
Hi Can you help me in my problem?
checking if a time range contains another time range for example I have 2 time range:
$nightShiftStart = strtotime("22:00:00 today");
$nightShiftEnd = strtotime("06:00:00 tomorrow");
$overTimeStart = strtotime("21:00:00 today");
$overTimeEnd = strtotime("07:00:00 tomorrow");
if I check if overtime start and end contains night shift schedule it should return true. And I have a code for that.
if ($overTimeStart >= $nightShiftStart && $overTimeEnd <= $nightShiftEnd ) {
return true;
} else {
return false;
}
the code above will return true. but if I change the overtime range to this:
$nightShiftStart = strtotime("22:00:00 today");
$nightShiftEnd = strtotime("06:00:00 tomorrow");
$overTimeStart = strtotime("17:00:00 today");
$overTimeEnd = strtotime("20:00:00 today");
it also return true, it should return false because the overtime is only from 5pm to 8pm and the time not meet the Night Shift. Can you pls help me with this i've been stuck for 2days.
Take a look at the document: https://www.php.net/manual/en/datetime.formats.relative.php
Exceptions to this rule are: "yesterday", "midnight", "today", "noon" and "tomorrow". Note that "tomorrow 11:00" and "11:00 tomorrow" are different. Considering today's date of "July 23rd, 2008" the first one produces "2008-07-24 11:00" where as the second one produces "2008-07-24 00:00". The reason for this is that those five statements directly influence the current time.
So the correct strings should be:
$nightShiftStart = strtotime("today 22:00:00");
$nightShiftEnd = strtotime("tomorrow 06:00:00");
$overTimeStart = strtotime("today 17:00:00");
$overTimeEnd = strtotime("today 20:00:00");
I have a job that runs every 28 days. and I want to assign it a cycle number based on a starting reference date.
e.g
1st cycle is 01/27/22. and that cycle number would be 2201.
subsequently I want to calculate the cycle number based on the current date. but for each year there could be either 13 or 14 cycles.
I've managed to figure out the number of cycles since the reference date to figure out the latest cycle date (see below)
const REF_ZERO_DATE = '01/27/2022';
const REF_ZERO_CYCLE_YEAR = "22";
const REF_ZERO_CYCLE_NUM = "01";
$today = new \DateTime("2023/12/29");
echo ("Today = ".$today->format("Y/m/d")."\n");
$ref_zero = new \DateTime(self::REF_ZERO_DATE);
echo ("ref_zero = ".$ref_zero->format("Y/m/d")."\n");
$number_of_days_since_ref_zero = $today->diff($ref_zero)->format("%a");
echo ("Number of days since ref zero = ".$number_of_days_since_ref_zero."\n");
$number_of_cycles_since_ref_zero = floor($number_of_days_since_ref_zero/28);
echo ("Number of cycles since ref zero = ".$number_of_cycles_since_ref_zero."\n");
$interval = 'P' . $number_of_cycles_since_ref_zero*28 . 'D';
echo ("Interval = ".$interval);
$date_of_lastest_cycle = date_add($ref_zero,new \DateInterval($interval));
echo ("last Cycle Date = ".$date_of_lastest_cycle->format("Y/m/d")."\n");
But my math for the cycle adjustment is missing coping with 12 or 13 cycle in a specific year.
It is not explicitly stated whether the cycle of the previous year continues into the next or not.
The scenario in which the cycles can overlap between years is more complicated, so this is assumed.
The interval count code was extracted to the following function:
function calculateIntervalCount($startDate, $endDate, $interval) {
$start = new \DateTime($startDate);
$end = new \DateTime($endDate);
$interval = new \DateInterval($interval);
$periodDays = intval($end->diff($start)->format('%a'));
$intervalDays = intval($interval->format('%d'));
return floor($periodDays / $intervalDays);
}
There are two cases when calculating the interval count of a particular year:
year of start and end are the same year
year of end is after year of start
In the first case the interval count is the same as the interval count of the whole period.
In the second case the interval count of a particular year can be calculated from the difference between the interval counts of the whole period and the period before the end year.
The following function returns the cycle number:
function calculateCycleNumber($startDate, $endDate, $interval) {
$totalCycles = calculateIntervalCount($startDate,$endDate,$interval);
$startYear = intval((new \DateTime($startDate))->format('Y'));
$endYear = intval((new \DateTime($endDate))->format('Y'));
if($startYear < $endYear) {
$endOfLastYearDate = (new \DateTime($endDate))->modify('last day of December last year')->format('Y-m-d');
$cyclesSinceEndOfLastYear = calculateIntervalCount($endOfLastYearDate, $endDate, $interval);
$yearCycle = $totalCycles - $cyclesSinceEndOfLastYear + 1;
} else {
$yearCycle = $totalCycles;
}
$yearCode = substr($endYear,-2);
$yearCycleCode = sprintf('%02d', $yearCycle);
return $yearCode . $yearCycleCode;
}
A cycle number of 2314 was obtained with the inputs provided.
echo calculateCycleNumber('01/27/2022','2023/12/29','P28D');
Note that 14 is possible in case of overlapping cycles.
You can use timestamp, where you add 28 days each time so you get the next date and so on.
Get the next timestamp
$next_date = strtotime('+28 day', $timestamp);
Convert to readable date
echo date('m/d/Y', $next_date);
I am using PHP, jQuery AJAX and HTML to create a timesheet system, for this the user needs to select 2 dates within 1 month of each other. The system as yet is working and shows (very limited) data.
BUT! When I actually select a date over the month limit (i.e. 2 months further than the start or another year after the start), it still shows the table with the data.
For this I have this check:
$dt1 = new DateTime($_REQUEST['startdate']);
$dt2 = new DateTime($_REQUEST['enddate']);
$diff = date_diff($dt1, $dt2);
// I have tried this the other way around and get the same result...
if($diff->m > 1 || $diff->y > 1)
{
print("<center><strong>Time between dates it too great<br />Please choose another date or time within a month of each other</strong></center>");
die();
}
The dates are passed by a jQuery datepicker object via AJAX, and the dates I use, for example, are passed as such:
11/14/2015 (start date) && 12/14/2015 (end date) - should show data
09/14/2015 (start date) && 12/14/2015 (end date) - should not show data but does
11/14/2015 (start date) && 12/14/2016 (end date) - should not show data but does
There is a check in place that sees if the dates given start before the other and this works, I have tried the same kind of thing for this check, but without success, this check is as such:
function CountDaysBetween($startDate, $endDate)
{
$begin = strtotime($startDate);
$end = strtotime($endDate);
if ($begin > $end) {
echo "start date is in the future! <br />";
return;
} else {
$no_days = 0;
$weekends = 0;
while ($begin <= $end) {
$no_days++; // no of days in the given interval
$what_day = date("N", $begin);
if ($what_day > 5) { // 6 and 7 are weekend days
$weekends++;
};
$begin += 86400; // +1 day
};
$working_days = $no_days - $weekends;
return $working_days + 1;
}
}
Edit
Dates 2 or more months apart within the same year work, tested again and this is the case, but dates into the next year do not
In your first part of the php code, you have put this operator>, but the problem is it means, everything Smaller than 1, not everything that is smaller than one or equal to 1. The easy solution is to change the operators to >=; which means everything that is equal to 1 or smaller than 1.
The date_diff constructs in PHP suck monkeyballs. Far more practical is to use straight comparisons instead:
$dt1 = new \DateTime($_REQUEST['startdate']);
$dt2 = new \DateTime($_REQUEST['enddate']);
$dt1->add(new \DateInterval('P1M'));
echo ($dt1 < $dt2 ? 'Less' : 'More') . ' than a month';
Also please do not use $_REQUEST, it has potentially terrible security issues. You should use $_GET, $_POST or $_COOKIE according to what you explicitly expect.
What is a better way in the code below to add a new value to the variables $timestop and $time_diff if the condition is met?
//Calculates difference in time using 24h format
$timestart = strtotime("14:00:00");
$timestop = strtotime("07:00:00"); //if smaller value, it must end next day and meets the condition below
$time_diff = $timestop - $timestart; //elapsed time
if ($time_diff < 0 || $time_diff == 0) //if result is negative value, $timestop ends next day
{
$timestop = strtotime( '+1 day' , strtotime("07:00:00") ); //+ 1 day changes timestamp
}
/* UPDATED */
$time_diff = $timestop - $timestart; //added again
echo $time_diff;
No, overwriting variables is no problem, and it's daily routine.
You are not even overwriting in any other type, you're just resetting to another integer value.
It's even better, because you don't waste any extra memory space (which of course is not high, but think of it in a big scale).
I have two times start_time=2009-12-01 9.30 pm and end_time=2009-12-01 11.30 pm(YYYY-MM-DD).If the user do any activity between these times ie at 2009-12-01 10.30 pm I need to tell him you are not valid to do this activity...
The two times 2009-12-01 9.30 pm and 2009-12-01 11.30 pm is taken from database.The time 2009-12-01 10.30 is given by user.
My question is how can I find the time 10.30pm is occured inbetween 9.30pm to 11.30pm...
I do my program in PHP
Use strtotime() to convert the strings into Unix seconds. Then a simple
if ($time1 < strtotime(10:30...) && strtotime(10:30...) < $time 2)
{
//do your stuff;
}
$start = strtotime($start_time);
$end = strtotime($end_time);
$user = strtotime($user_time);
if($user > $start && $user < $end) die('You are not allowed');
You can use database query or PHP. In PHP:
$timeStart = strtotime('2009-12-01 11.30');
$timeEnd = strtotime('2009-12-01 09.30');
$time = strtotime('2009-12-01 10.30');
if($time > $timeStart && $time < $timeEnd) {
echo "Between given times.";
}
convert "2009-12-01 9.30 pm" and "2009-12-01 11.30 pm" to unix timestamps, then compare those with <:
if ($start <= $event && $event < $end)
complain();
} else {
proceed();
}
There is no need to do any excessive PHP handling when you can simply use a SQL query:
SELECT 1 FROM your_table_name WHERE '2009-12-01 10:30:00' BETWEEN start_time AND end_time;
This will return 1 or more result(s) if the user activity occurs between any start and end times within the database. Please note you should have a leftmost prefix index on your table for (start_time, end_time).
Just check your query results. If you have a row count greater than or equal to 1 you know that the user activity falls between start and end times in your database.