Find a specific day of week based on a date - php

I would like to be able to find the date which "Sunday" falls on for a given date, formatted as YYYY-MM-DD.
... How would this be achieved in PHP?

strtotime() may help you, it accepts GNU-Date-input-formats like "next Sunday"
echo date('Y-m-d',strtotime('sunday',strtotime("2011-07-04 Z")));

Look at the time function for php.

If you can't find a library that does this, then:
Come up with a reference date (January 1, 1970?) for which you know the day of the week.
Calculate the number of days between the reference date and your given date.
Take that answer modulo 7.
Convert to a day of the week.

Here you have a full example with multiples values
it is for PHP or any other lenguage that uses epoch time (or similar)
<?php
function prevSunday($paramDay){
$aDay = 24*60*60;
$aWeek = $aDay * 7;
$sunday = $aDay + $paramDay - (($paramDay - 3 * $aDay) % $aWeek);
return $sunday;
}
$randDay = 1309819423 + rand(0, 9000000); // this contanis a random day (and hours, minutes, seconds)
$aSaterday = strtotime("20110702");
$aSunday = strtotime("20110703");
$aMonday = strtotime("20110704");
echoTwoDays($aSuterday, prevSunday($aSuterday));
echoTwoDays($aSunday, prevSunday($aSunday));
echoTwoDays($aMonday, prevSunday($aMonday));
/* echoes
day1: Saturday 20110702
day2: Sunday 20110626
day1: Sunday 20110703
day2: Sunday 20110703
day1: Monday 20110704
day2: Sunday 20110703
*/
echoTwoDays($randDay, prevSunday($randDay)); // echoes a random date and perv sunday
function echoTwoDays ($day1, $day2) {
echo "day1: " . date("l Ymd", $day1) ."<br>"; // remove l as your request
echo "day2: " . date("l Ymd", $day2) ."<br><br>"; // remove l as your request
}
function prevSunday($paramDay){
$aDay = 24*60*60;
$aWeek = $aDay * 7;
$sunday = $aDay + $paramDay - (($paramDay - 3 * $aDay) % $aWeek);
return $sunday;
}
?>

Related

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

PHP - How to check if current day/time is between two weekdays including time (from - to)

I need to check if current date and time is between two weekdays which include time (from and to). There can be multiple records in the db and week days are stored via PHP date('N') where 1 (for Monday) through 7 (for Sunday) as well as hour - minute is stored via time.
For instance, a stored rule can be the following:
week_day_from : 5 (Friday)
week_hour_from : 16:00:00
week_day_to : 7 (Sunday)
week_hour_to : 18:00:00
or even
week_day_from : 7 (Sunday)
week_hour_from : 10:00:00
week_day_to : 2 (Tuesday)
week_hour_to : 12:00:00
How can I determine if current day/time applies in one of the rules? The main idea is to hide some results if one of the rule applies (i.e. do not show this meal after friday 16:00 and before Sunday 18:00)
thank you in advance
The function getdate will give you more exact information. The function getDate() will return an array containing information about the weekday and time. By having the interval,you can determine if applies.
found something....
had to create pseudo dates in order to use strtotime and compare with current date time. Pseudo dates are created via conditions as shown below which are commented to describe my logic.
I would much better prefer a MySQL query based solution rather than fetching all rules and compare but I can not find a way. I would be gratefull if you check my code and tell me what you think. Flaw may be possible...
$daynow = date("N"); //$daynow = 7;
$datetimenow = date("d-m-Y G:i:s");
if($row['week_day_from'] > $row['week_day_to'])
{// case from saturday(6) to thursday(4)
if($daynow == 7)
{
$check_from = date("d-m-Y", strtotime("Sunday + ".$row['week_day_from']." Days - 1 week"));
$check_to = date("d-m-Y", strtotime("Sunday + ".$row['week_day_to']." Days"));
}
else
{
$check_from = date("d-m-Y", strtotime("Sunday + ".$row['week_day_from']." Days - 2 week"));
$check_to = date("d-m-Y", strtotime("Sunday + ".$row['week_day_to']." Days - 1 week"));
}
}
else
{// case from thursday(4) to saturday(6)
if($daynow == 7)
{
$check_from = date("d-m-Y", strtotime("Sunday + ".$row['week_day_from']." Days"));
$check_to = date("d-m-Y", strtotime("Sunday + ".$row['week_day_to']." Days"));
}
else
{
$check_from = date("d-m-Y", strtotime("Sunday + ".$row['week_day_from']." Days - 1 week"));
$check_to = date("d-m-Y", strtotime("Sunday + ".$row['week_day_to']." Days - 1 week"));
}
}
if
(
strtotime($datetimenow) >= strtotime($check_from." ".$row['week_hour_from'])
AND
strtotime($datetimenow) <= strtotime($check_to." ".$row['week_hour_to'])
)
{
//RULE APPLIES
}

add days to month not exceeding last day of the month php

I have date in this form - - 20160428000000 (28th April 2016) i.e yyyymmdd...
I need that if some days(eg. 3) are added to this date - it should add them but not exceed the month(04) - expected output - 20160430000000 - 30th April
Similarly, 20160226000000 + 5days should return 20160229000000 i.e leap year Feb. That means, it should not jump to another month.
Any hints/Ideas ?
Another alternative would be to use DateTime classes to check it out:
First of course create your object thru the input. Then, set the ending day of the month object.
After that, make the addition then check if it exceeds the ending day. If yes, set it to the end, if not, then get the result of the addition:
$day = 5; // days to be added
$date = '20160226000000'; // input date
$dt = DateTime::createFromFormat('YmdHis', $date); // create the input date
$end = clone $dt; // clone / copy the input
$end->modify('last day of this month'); // and set it to last day
$dt->add(DateInterval::createFromDateString("+{$day} days")); // add x days
// make comparision
$final_date = ($dt > $end) ? $end->format('YmdHis') : $dt->format('YmdHis');
echo $final_date;
For this you can try like this:
$given_date = 20160428000000;
$no_of_day = 3;
if(date('m',strtotime($given_date)) < date('m',strtotime($given_date ." +".$no_of_day."days"))){
echo "Exceeded to next month <br/>";
echo "Last date of month should be: ".date("t M Y", strtotime($given_date));
}
else {
echo "Next date will be after ".$no_of_day." day(s)<br/>";
echo date('d M Y',strtotime($given_date ." +".$no_of_day."days"));
}
If month will jump to next month then it will show the current month last date.
other wise it will show date after number of days extended.
If the added date exceeds last day, will select the last day as the new date.
<?php
$date_orig = 20160226000000;
$add_day = 5; # No. of days to add
$added_date = strtotime($date_orig. ' + '.$add_day.' days'); // Add $add_day to $date_orig
$last_date = strtotime(date("YmtHis", strtotime($date_orig))); // Last day of $date_orig
$new_date = ($added_date > $last_date) ? $last_date : $added_date; // check the added date exceeds the last date
$new_date_format = date("YmdHis", $new_date); // Format Date
echo $new_date_format;
?>
<?php
$month_end = date('t-m-Y'); // Gets the last day of the month; e.g 31-07-2019
echo $month_end;
?>

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.

Finding all weekdays in a month

How do I go about getting all the work days (mon-fri) in a given time period (let's say, today till the end of the next month) ?
If you're using PHP 5.2+ you can use the library I wrote in order to handle date recursion in PHP called When.
With the library, the code would be something like:
$r = new When();
$r->recur(<start date here>, 'weekly')
->until(<end date here>)
->wkst('SU')
->byday(array('MO', 'TU', 'WE', 'TH', 'FR'));
while($result = $r->next())
{
echo $result->format('c') . '<br />';
}
This sample does exactly what you need, in an quick and efficient way.
It doesn't do nested loops and uses the totally awesome DateTime object.
$oDateTime = new DateTime();
$oDayIncrease = new DateInterval("P1D");
$aWeekDays = array();
$sStart = $oDateTime->format("m-Y");
while($oDateTime->format("m-Y") == $sStart) {
$iDayInWeek = $oDateTime->format("w");
if ($iDayInWeek > 0 && $iDayInWeek < 6) {
$aWeekDays[] = clone $oDateTime;
}
$oDateTime->add($oDayIncrease);
}
Try it here: http://codepad.org/wuAyAqnF
To use it, simply pass a timestamp to get_weekdays. You'll get back an array of all the weekdays, as timestamps, for the rest of the current month. Optionally, you can pass a $to argument - you will get all weekdays between $from and $to.
function get_weekdays ($from, $to=false) {
if ($to == false)
$to = last_day_of_month($from);
$days = array();
for ($x = $from; $x < $to; $x+=86400 ) {
if (date('w', $x) > 0 && date('w', $x) < 6)
$days[] = $x;
}
return $days;
}
function last_day_of_month($ts=false) {
$m = date('m', $ts);
$y = date('y', $ts);
return mktime(23, 59, 59, ($m+1), 0, $y);
}
I suppose you could loop through the dates and check the day for each one, and increment a counter.
Can't think of anything else off the top of my head.
Pseudocode coming your way:
Calculate the number of days between now and the last day of the month
Get the current day of the week (i.e. Wednesday)
Based on the current day of the week, and the number of days left in the month, it's simple calculation to figure out how many weekend days are left in the month - it's going to be the number of days remaining in the month, minus the number of Sundays/Saturdays left in the month.
I would write a function, something like:
daysLeftInMonth(daysLeftInMonth, startingDayOfWeek, dayOfWeekToCalculate)
where:
daysLeftInMonth is last day of the month (30), minus the current date (15)
startingDayOfWeek is the day of the week you want to start on (for today it would be Wednesday)
dayOfWeekToCalculate is the day of the week you want to count, e.g. Saturday or Sunday. June 2011 currently has 2 Sunday, and 2 Saturdays left 'til the end of the month
So, your algorithm becomes something like:
getWeekdaysLeft(todaysDate)
...getWeekdaysLeft is something like:
sundaysLeft = daysLeftInMonth(lastDayOfMonth - todaysDate, "Wednesday", "Sunday");
saturdaysLeft = daysLeftInMonth(lastDayOfMonth - todaysDate, "Wednesday", "Saturday");
return ((lastDayOfMonth - todaysDate) - (sundaysLeft + saturdaysLeft));
This code does at least one part you ask for. Instead of "end of next month" it simply works with a given number of days.
$dfrom = time();
$fourweeks = 7 * 4;
for ($i = 0; $i < $fourweeks; $i ++) {
$stamp = $dfrom + ($i * 24 * 60 * 60);
$weekday = date("D", $stamp);
if (in_array($weekday, array("Mon", "Tue", "Wed", "Thu", "Fri"))) {
print date(DATE_RSS, $stamp) . "\n";
}
}
// Find today's day of the month (i.e. 15)
$today = intval(date('d'));
// Define the array that will hold the work days.
$work_days = array()
// Find this month's last day. (i.e. 30)
$last = intval(date('d', strtotime('last day of this month')));
// Loop through all of the days between today and the last day of the month (i.e. 15 through 30)
for ( $i = $today; $i <= $last; $i++ )
{
// Create a timestamp.
$timestamp = mktime(null, null, null, null, $i);
// If the day of the week is greater than Sunday (0) but less than Saturday (6), add the timestamp to an array.
if ( intval(date('w', $timestamp)) > 0 && intval(date('w', $timestamp)) < 6 )
$work_days[] = mktime($timestamp);
}
The $work_days array will contain timestamps which you could use this way:
echo date('Y-m-d', $work_days[0]);
The code above with work in PHP 4 as well as PHP 5. It does not rely on the functionality of the DateTime class which was not available until PHP 5.2 and does not require the use of "libraries" created by other people.

Categories