Convert past date to next day of week in PHP - php

I'm trying to make stream events repeat weekly. I've written the code below which works but seems obtuse. Is there a better way to go about this?
A diagram of what I'd like to happen.
If the event date is in the past, update the event date to the nearest future day of the week that the event was originally on.
(I added the check to see if it was currently the same day as the original stream day because PHP's Stringtotime "This Tuesday" would jump to Tuesday of next week if today was Tuesday. Is there a better way around this?)
I'm relatively new to php so any help would be great!
// If a stream is set to weekly, and it's already over, this code updates its start and end times to the next day week day that it originally aired on.
if( ($weekly = true) && ($stream_end_epoch < $now) ){ //If Stream end date has past & repeat is turned on.
$stream_day_epoch = strtotime(get_post_meta( $stream_id, 'stream_day', true ));
$dayOfWeek = date("l", $stream_day_epoch);
$currentDate = new DateTime("now", new DateTimeZone($time_zone) );
$currentDay = $currentDate->format('l');
//Update the stream dates to the soonest week day they aired on.
if($dayOfWeek == $currentDay){
$stream_start_epoch = strtotime('Today '. $stream_start . $time_zone ); // update start (Set to yesterday because I'm getting a weird 1 day offset that I dont know where its coming from. this is super hackey and will probably break at certain times in the day, but i'm leaving it in this code until I can figure out a real solution.)
$stream_end_epoch = strtotime('Today '. $stream_end . $time_zone ); // update end.
}else{
$stream_start_epoch = strtotime('this '.$dayOfWeek. $stream_start . $time_zone ); // update start
$stream_end_epoch = strtotime('this '.$dayOfWeek. $stream_end . $time_zone ); // update end.
}
}

I think this could work for you:
$event_date = strtotime('2021-06-9');
$today = strtotime(date('Y-m-d'));
if($event_date < $today):
$dayOfWeek = date("l", $event_date);
$todayDay = date("l", $today);
$event_date = ($dayOfWeek !== $todayDay) ? strtotime("next " . $dayOfWeek) : $today;
endif;
var_dump(date('Y-m-d', $event_date));
if you set the event_date (for example) to 2021-06-04 (last Friday) the comparison will find that today is also Friday, so today is your next event day (and not on Friday of next week).

Related

Define the due date from a ticket creation date php

I am building a SLA KPI.
The SLA is based on ticket type and priority, each of these have a due date.
The thing is, I only have the field created_at, I don't have this due date, so I need to calculate it, and as mentioned above, use the params priority and type to define the right date.
But my real problem is, how to calculate it on PHP, considering operation days and hours, monday to friday, 8:00 to 18:00
For example.
The ticket was created at 2019-06-04 08:00:00 and its deadline is 16 hours.
So it would be, 2019-06-06 08:00:00
After digging a lot looking for a answer, I've found a function that solved my problem.
function addRollover($givenDate, $addtime, $dayStart, $dayEnd, $weekDaysOnly) {
//Break the working day start and end times into hours, minuets
$dayStart = explode(',', $dayStart);
$dayEnd = explode(',', $dayEnd);
//Create required datetime objects and hours interval
$datetime = new DateTime($givenDate);
$endofday = clone $datetime;
$endofday->setTime($dayEnd[0], $dayEnd[1]); //set end of working day time
$interval = 'PT'.$addtime.'H';
//Add hours onto initial given date
$datetime->add(new DateInterval($interval));
//if initial date + hours is after the end of working day
if($datetime > $endofday)
{
//get the difference between the initial date + interval and the end of working day in seconds
$seconds = $datetime->getTimestamp()- $endofday->getTimestamp();
//Loop to next day
while(true)
{
$endofday->add(new DateInterval('PT24H'));//Loop to next day by adding 24hrs
$nextDay = $endofday->setTime($dayStart[0], $dayStart[1]);//Set day to working day start time
//If the next day is on a weekend and the week day only param is true continue to add days
if(in_array($nextDay->format('l'), array('Sunday','Saturday')) && $weekDaysOnly)
{
continue;
}
else //If not a weekend
{
$tmpDate = clone $nextDay;
$tmpDate->setTime($dayEnd[0], $dayEnd[1]);//clone the next day and set time to working day end time
$nextDay->add(new DateInterval('PT'.$seconds.'S')); //add the seconds onto the next day
//if the next day time is later than the end of the working day continue loop
if($nextDay > $tmpDate)
{
$seconds = $nextDay->getTimestamp()-$tmpDate->getTimestamp();
$endofday = clone $tmpDate;
$endofday->setTime($dayStart[0], $dayStart[1]);
}
else //else return the new date.
{
return $endofday;
}
}
}
}
return $datetime;
}
Thank you all.

Converting hours to timestamps

To convert a date to timestamp, I usually do this- strtotime ("2018-05-17 05:04:34) but now, I want to convert just hours (without date) e.g. 02:00:00 to timestamp. How do I do this?
Why I need this is to compare if a certain time is greater than the hour specified. This is what I am doing:
$reported = strtotime("2018-05-17 05:04:34");
$respons = strtotime("2018-05-17 17:04:34);
$response_time = $respons - $reported;
I want to be to check if $response_time is greater than 1 hour.
There is DateTime::diff, which probably does what you need
https://secure.php.net/manual/de/datetime.diff.php
In your case that should be
$datetime1 = new DateTime("2018-05-17 05:04:34");
$datetime2 = new DateTime("2018-05-17 17:04:34);
$interval = $datetime1->diff($datetime2);
echo $interval->format('H hours');
Strtotime has no problem parsing a time without a date.
No need to fake a date which will come back and bite you with daylight savings.
I also added a check to see if the start/end is "reversed".
$start= "2018-05-17 05:04:34";
$end = "2018-05-17 17:04:34";
//Note that it's intentionally reversed
$diff = strtotime(substr($start,11))-strtotime(substr($end,11));
//If the calculation was reversed add one day in seconds
if($diff <0) $diff += 86400;
If($diff >3600){
Echo "more than one hour";
}Else{
Echo "less than one hour";
}
https://3v4l.org/g1jZH
I believe only I have understood your question correctly.
I want to convert just hours (without date) e.g. 02:00:00 to timestamp.
There's no Date component here.
Okay, I assume they are of same date. If that's the case, just append an arbitrary date in front of the two to make the strtotime() function work:
$start = "05:04:34";
$end = "17:04:34";
$reported = strtotime("2018-05-17 " . $start);
$respons = strtotime("2018-05-17 " . $end);
$response_time = $respons - $reported;
if ($response_time > 3600)
echo "More than hour!";
else
echo "Less than hour!";
Note: This doesn't work if the start time is 17:00 and end time is say, 08:00 - which occurs in the next day. You have to make sure if the start time is greater than end time, then you have to add one more day to the end time.
I like the DateTime class, give this a try:
<?php
$reported = new DateTime('2018-05-17 05:04:34');
$reported->modify('+2 hours');
$now = new DateTime();
echo $now < $reported ? 'less than 2 hours' : 'more than 2 hours';
See it here https://3v4l.org/T7BEL
See the DateTime class docs here http://php.net/manual/en/class.datetime.php

PHP select the dates of a custom week range

PHP 7.1.7
There's a work function I'm dealing with that has a custom "week" (where a "week" for this function is Saturday through Friday).
For any given day of the week, how could I set two variables to contain the start of the custom defined week (Saturday) and the end of the custom defined week (Friday).
So, if I had a date of 8-11-17, I would need to come up with a a start date variable holding 8-05-17 and an end date variable holding 8-11-17.
Thanks
Not sure if I understood the question correct but is this what you are looking for?
It uses strtotime() to find previous saturday from input. Then next friday from that saturday.
$Input = "08/12/2017";
if(date("l", strtotime($Input)) == "Saturday"){
$Saturday = strtotime($Input);
}else{
$Saturday = strtotime($Input . " previous saturday");
}
$Friday = strtotime(date("m/d/Y", $Saturday) . " next friday");
echo date("m/d/Y", $Saturday) . " to " . date("m/d/Y", $Friday);
https://3v4l.org/l4g8D
EDIT; I just noticed if the Input is a saturday my code choosed the wrong dates. Corrected.
you could use date('w') to determine the day of week for given date.
If the number found is less than 6, move that number + 1 backwards. That's your starting date. End date will be 7 days later:
<?php
$date = new DateTime('08-11-2017');
$daynumber = $date->format('w');
if($daynumber < 6) {
$tomove = $daynumber + 1;
$date->modify('-' . $tomove.'day');
}
$startdate = $date;
$enddate = clone $date;
$enddate->modify('+7day');
echo $startdate->format('d-m-y');
echo $enddate->format('d-m-y');
?>
edit
forgot the word "day" in modify

recurring date functions in php

Good Day,
I am trying to create a recurring date system that has the following:
nth day of nth month (2nd day of every 3rd month)
$this_months_friday = strtotime('+3 days +4 months');
the output of that will always be current day + 3 days of the 4th month.
how do I get it to display the nth day of the nth month?
since i also tried
$this_months_friday = strtotime('every 3 days +4 months');
and it did not return any result. Should i stick with strtotime on this one or move to DateTime function of php. though i wont still be able to formulate the proper argument for that kind of date sequence.
Any help would be greatly appreciated.
Thank You.
Probably better off using DateTime with a couple intervals:
$d = new DateTime();
$d->add(new DateInterVal('P' . $days . 'D'))->add('new DateInterVal('P' . $months . 'M'));
not sure what youre two example intervals are wanting.
You want an internval to start in 4 months, which then repeats every 3 days?
That'd be something more like
$d = new DateTime();
$d->add(new DateInterval('P4M')); // jump ahead 4 months immediately
$day3 = new DateInterval('P3D');
for ($i = 0; $i < 100; $i++) {
$d->add($day3); // jump ahead 3 days
... do something with this new date
}
for a basic recurring event, +4 months + 3 days, you'd simply have one interval:
$interval = new DateInteval('P4M3D'); // +4 months +3 days
$date = new DateTime();
while($some_condition) {
$date->add($interval);
do_something();
}
You can do this by saving the values in variables like that :
$day=3;
$month=4;
echo date("d-m-y",strtotime('+'.$day .'days' .'+'.$month.'months'));
Explanation:
7(july)+4 months = 11 month(November)
8 july+ 3 days = 11 july
Output:
11-11-13
NOTE: just for the example I have put the values hard coded, You can make them dynamic.

How do I get next occurrence of a certain day of the month

I am trying to get stripe to set a end_trial date on the next occurrence of whatever day of the month the user chooses. i.e. If today is the 16th and the user chooses the 15th I need the unix timestamp for the 15th of the next month. However if today was the 14th I need the timestamp for tomorrow.
I tried the solution found on this SO question Find the date for next 15th using php .
When i ran the code suggested in that question and substituted 15 for 31
$nextnth = mktime(0, 0, 0, date('n') + (date('j') >= 31), 31);
echo date('Y-m-d', $nextnth);
The result is 2013-03-03
I also tried this one Get the date of the next occurrence of the 18th .
The second one would actually give me 2013-03-31 when i ran it one 2013-1-31.
Both had unexpected results. Is february the problem? Any guidance will be much appreciated.
Here is a way to do it.
function nextDate($userDay){
$today = date('d'); // today
$target = date('Y-m-'.$userDay); // target day
if($today <= $userDay){
$return = strtotime($target);
}
else{
$thisMonth = date('m') + 1;
$thisYear = date('Y');
if($userDay >= 28 && $thisMonth == 2){
$userDay = 28;
}
while(!checkdate($thisMonth,$userDay,$thisYear)){
$thisMonth++;
if($thisMonth == 13){
$thisMonth = 1;
$thisYear++;
}
}
$return = strtotime($thisYear.'-'.$thisMonth.'-'.$userDay);
}
return $return;
}
// usage
echo date('Y-m-d',nextDate(29));
We get the user's choice and compare it today.
If today is less than or equal to user choice, we return the timestamp for this month.
If today is greater than user choice, we loop through dates, adding a month (or a year if it's $thisMonth hits 13). Once this date does exist again, we have our answer.
We check the dates using php's checkdate function, strtotime and date.
I really don't understand the question completely. You can easily determine the date for next 30 days for example
$next_ts = time() + 30 * 86400; // add 30 days to current timestamp
$next = date('Y-m-d', $next_ts); // format string as Y-m-d
echo $next;
If that is not what you need, please explain the problem.

Categories