I'm trying to create a list of the date of the first saturday each month.
Ideally I'd like it to show the next 6 dates.
I'm thinking of something like
function getSaturday($y, $m)
{
return new DatePeriod(
new DateTime("first saturday of $y-$m"),
DateInterval::createFromDateString('next saturday')
);
}
usage
foreach (getSaturday(2023, 11) as $saturday) {
echo $saturday->format("l, Y-m-d\n");
}
however this is code I have found and it currently just shows all the Saturdays in the next month. Can anyone help me out with the required changes please?
You can do with a simple loop.
const firstSaturday = 'first saturday of next month';
$months = [];
$month = new DateTime(firstSaturday);
for ($i = 0; $i < 6; $i++) {
$months[] = $month->format('Y-m-d');
$month->modify(firstSaturday);
}
print_r($months);
Output
2022-12-03
2023-01-07
2023-02-04
2023-03-04
2023-04-01
2023-05-06
Related
I have the following code so far:
$months = array();
$numJoin = date("n",strtotime($me['joinTime']));
$numLast = date('n', strtotime('Dec 31'));
$numCurrent = date("n",strtotime('2016-06-01'));
array_push($months, date("F", strtotime($me['joinTime'])));
for($i = ($numJoin + 1); $i <= $numLast; $i++) {
if($numCurrent>$numJoin) {
$dateObj = date_create_from_format('!m', $i);
array_push($months, $dateObj->format('F'));
}
$numCurrent= -1;
}
What I'm trying to do here is to add into the array current month that kicks in, and save previous months in the array like for example:
Start month is -> May
June kicks in -> I add June into the array (now I should have May and June in array).
July kicks in -> I add July into the array (now I should have May, June and July in array).
How can I do this achieve this? Current solution works only for +1 month.. I can't add more than 1 month :/
P.S. New item should only be added when the new month kicks in, and previous content of the array should be saved...
Here we go, you need to check that your month is less than the current month or not. Check Online
$months = array();
$num = date("n",strtotime($me['joinTime'])); //join month number
$now = date("n"); //Current month number
for($i = $num; $i <= $now; $i++){
$dateObj = DateTime::createFromFormat('!m', $i);
array_push($months, $dateObj->format('F'));
}
print_r($months);
I'm still a little confused, but I think this is what you are after... all month names after the join month and until current month...
$me = array('joinTime'=>'2016-03-01');
$dtCurrent = strtotime($me['joinTime']);
$arrMonths = array();
while($dtCurrent < time()) {
$dtCurrent = strtotime("+1 month",$dtCurrent);
$arrMonths[] = date('F',$dtCurrent);
}
var_dump($arrMonths);
How to manipulate the date and exclude saturday and sunday?. The objective is, I need to create a cron job that will run and execute on datas that were created 5 days ago,"BUT", saturday and sunday shouldn't be included in that 5 days period.
here's what I have so far
$numdays = 5;
$today = strtotime('now');
$start = date('Y-m-d',strtotime('-'.$numdays.' day',$today));
echo $start;
if you try to run my code snippet above, it will show you the exact date 5 days ago 2016-02-10. But that one doesn't "exclude" saturday and sunday in the computation. it should be be 2016-02-08. So how to do that?
You can use PHP's date week of day, there are several versions, here is one using N:
<?php
$current = new DateTime();
$interval = new DateInterval('P1D');
$x = 5;
while ($x > 1) {
// Check if day of week is not saturday/sunday (1 => Monday ... 7 -> Sunday)
if ($current->format('N') >= 6) {
$x++;
}
$current->sub($interval);
$x--;
}
echo $current->format('Y-m-d') . PHP_EOL;
Example Run.
You can get a whole week and discard the weekends, keeping the furthest element in the array as a result.
$days = array_filter(array_map(function ($daysBack) {
$date = new \DateTimeImmutable("$daysBack days ago", new \DateTimeZone('UTC'));
return (!in_array($date->format('N'), [6, 7])) ? $date : null;
}, Range(1, 7)));
$fiveWorkingDaysAgo = end($days);
I am building multi-calendar, I have a horizontal looking interface:
I am trying to run the days of the week S,M,T,W,T,F,S
throughout the whole month instead of just the first 7 as in the picture.
the function which draw the calendar:
//our case "SUN"
if(AC_START_DAY=="sun"){
for($k=0; $k<7; $k++){
$weekday = mb_substr($lang["day_".$k.""],0,1,'UTF-8');
$list_day_titles.='<li class="cal_weekday"> '.$weekday.'</li>';
}
}
//If we chose Monday as start week.
else{
if ($first_week_day == 0) $first_week_day =7;
for($k=1; $k<=7; $k++){
if($k==7) $weekday = mb_substr($lang["day_0"][0],0,1,'UTF-8');
else $weekday = mb_substr($lang["day_".$k.""],0,1,'UTF-8');
$list_day_titles.='<li title="'.$lang["day_".$k.""].'"> '.$weekday.'</li>';
}
}
The lang file:
$lang["day_0"] = "Sunday";
$lang["day_1"] = "Monday";
$lang["day_2"] = "Tuesday";
$lang["day_3"] = "Wednesday";
$lang["day_4"] = "Thursday";
$lang["day_5"] = "Friday";
$lang["day_6"] = "Saturday";
Already defined
$month=sprintf("%02s",$month);
// define vars
$today_timestamp = mktime(0,0,0,date('m'),date('d'),date('Y')); # current timestamp - used to check if date is in past
$this_month = getDate(mktime(0, 0, 0, $month, 1, $year)); # convert month to timestamp
$first_week_day = $this_month["wday"]; # define first weekday (0-6)
$days_in_this_month = cal_days_in_month(CAL_GREGORIAN,$month,$year); # define number of days in week
$day_counter_tot = 0; # count total number of days showin INCLUDING previous and next months - use to get 6th row of dates
Looks like the $lang["day_".$k.""] is just counting the days from 0 to 6.. how can i make is loop untill the end of the month?
NOTE: I tried increasing the $k<7 just more empty blue boxes appear.
Use the loop to the 30/31 day.
And then change this line
$weekday = mb_substr($lang["day_".$k.""],0,1,'UTF-8');
to
$weekday = mb_substr($lang["day_".$k%7.""],0,1,'UTF-8');
This should give you the day 0 for every sunday.
0 % 7 = 0 (sunday)
1 % 7 = 1 (monday)
...
7 % 7 = 0 (sunday again)
8 % 7 = 1 (monday again)
You can use this code to generate all the days of the current month.
for ($date = strtotime(date('Y-m-01')); $date < strtotime(date('Y-m-t')); $date = strtotime("+1 day", $date)) {
echo date("l-d", $date)."<br>";
}
Will print all the days of the current month as follows.
Thursday-01
Friday-02
Saturday-03
Sunday-04
Monday-05
Tuesday-06
Wednesday-07
Thursday-08
Friday-09
Saturday-10
Sunday-11
Monday-12
Tuesday-13
Wednesday-14
Thursday-15
Friday-16
Saturday-17
Sunday-18
Monday-19
Tuesday-20
Wednesday-21
Thursday-22
Friday-23
Saturday-24
Sunday-25
Monday-26
Tuesday-27
Wednesday-28
Thursday-29
Friday-30
Looks like you almost got it right.
You only need to slightly modify your code to make it work the way you want it to.
You should just change your code to:
$number_of_days_in_the_future = 42; // Here you can put in the number of days for which you want to display the corresponding letter, and based on your screenshot that is 42
//our case "SUN"
if(AC_START_DAY=="sun"){
for($i=0; $i<$number_of_days_in_the_future; $i++){
$k = $i % 7;
$weekday = mb_substr($lang["day_".$k.""],0,1,'UTF-8');
$list_day_titles.='<li class="cal_weekday"> '.$weekday.'</li>';
}
}
//If we chose Monday as start week.
else{
if ($first_week_day == 0) $first_week_day =7;
for($i=1; $i<=$number_of_days_in_the_future; $i++){
$k = $i % 7;
if($k==7) $weekday = mb_substr($lang["day_0"][0],0,1,'UTF-8');
else $weekday = mb_substr($lang["day_".$k.""],0,1,'UTF-8');
$list_day_titles.='<li title="'.$lang["day_".$k.""].'"> '.$weekday.'</li>';
}
}
Please note that I only tried to fix your code so it works as you expect it to.
There's probably a more elegant solution but I don't really know your full code so I would just be guessing if I tried to offer you another approach.
I hope this will help you.
Cheers
I want to calculate all Sunday's between given two dates. I tried following code. It works fine if days are less but if i enter more days. It keeps processing and Maximum execution time exceeds i changed the time but it even keeps processing even execution time is 200sec.
code is
<?php
$one="2013-01-01";
$two="2013-02-30";
$no=0;
for($i=$one;$i<=$two;$i++)
{
$day=date("N",strtotime($i));
if($day==7)
{
$no++;
}
}
echo $no;
?>
please help.
John Conde's answer is correct, but here is a more efficient and mathy solution:
$start = new DateTime('2013-01-06');
$end = new DateTime('2013-01-20');
$days = $start->diff($end, true)->days;
$sundays = intval($days / 7) + ($start->format('N') + $days % 7 >= 7);
echo $sundays;
Let me break it down for you.
$start = new DateTime('2013-01-06');
$end = new DateTime('2013-01-20');
First, create some DateTime objects, which are powerful built-in PHP objects meant for exactly this kind of problem.
$days = $start->diff($end, true)->days;
Next, use DateTime::diff to find the difference from $start to $end (passing true here as the second parameter ensures that this value is always positive), and get the number of days between them.
$sundays = intval($days / 7) + ($start->format('N') + $days % 7 >= 7);
Here comes the big one - but it's not so complicated, really. First, we know there is one Sunday for every week, so we have at least $days / 7 Sundays to begin with, rounded down to the nearest int with intval.
On top of that, there could be a Sunday in a span of time less than a week; for example, Friday to Monday of the next week contains 4 days; one of them is a Sunday. So, depending on when we start and end, there could be another. This is easy to account for:
$start->format('N') (see DateTime::format) gives us the ISO-8601 day of the week for the start date, which is a number from 1 to 7 (1 is Monday, 7 is Sunday).
$days % 7 gives us the number of leftover days that don't divide evenly into weeks.
If our starting day and the number of leftover days add up to 7 or more, then we reached a Sunday. Knowing that, we just have to add that expression, which will give us 1 if it's true or 0 if it's false, since we're adding it to an int value.
And there you have it! The advantage of this method is that it doesn't require iterating over every day between the given times and checking to see if it's a Sunday, which will save you a lot computation, and also it will make you look really clever. Hope that helps!
<?php
$no = 0;
$start = new DateTime('2013-01-01');
$end = new DateTime('2013-04-30');
$interval = DateInterval::createFromDateString('1 day');
$period = new DatePeriod($start, $interval, $end);
foreach ($period as $dt)
{
if ($dt->format('N') == 7)
{
$no++;
}
}
echo $no;
See it in action
Here is a solution if you want the Sundays in a specific date range.
function dateRange($begin, $end, $interval = null)
{
$begin = new DateTime($begin);
$end = new DateTime($end);
$end = $end->modify('+1 day');
$interval = new DateInterval($interval ? $interval : 'P1D');
return iterator_to_array(new DatePeriod($begin, $interval, $end));
}
/* define date range */
$dates = dateRange('2018-03-01', '2018-03-31');
/* define weekdays */
$weekends = array_filter($dates, function ($date) {
$day = $date->format("N");
return $day === '6' || $day === '7';
});
/* weekdays output */
foreach ($weekends as $date) {
echo $date->format("D Y-m-d") . "</br>";
}
/* define sundays */
$sundays = array_filter($dates, function ($date) {
return $date->format("N") === '7';
});
/* sundays output */
foreach ($sundays as $date) {
echo $date->format("D Y-m-d") . "</br>";
}
/* define mondays */
$mondays = array_filter($dates, function ($date) {
return $date->format("N") === '1';
});
/* mondays output */
foreach ($mondays as $date) {
echo $date->format("D Y-m-d") . "</br>";
}
Just change the number for any days you want in your output:
Monday = 1
Tuesday = 2
Wednesday = 3
Thursday = 4
Friday = 5
Saturday = 6
Sunday = 7
I searched the millions of similar posts about this but cannot find how to make it count down from 31, 30, 29, 28 etc.
I can have the previous calendar blocks show the 31st but that's all. I need it to show previous month 31st, 30, 29, etc.
updated code from Renku:
//define the variable dayCol
$dayCol = 0;
// Print last months' days spots.
for ($i=0; $i<$leadInDays; $i++) {
$lastmonth = date('d', strtotime(-$i.' day', strtotime($startDate))); // Days in previous month
print "<td width=\"14%\" height=\"25%\" class=\"calendar_cell_disabled_middle\">$lastmonth</td>\n ";
$dayCol++;
}
example :
I am writing a new loop for this.
<?php
$StartDate= date("Y-F-d",strtotime("+0 Month"));// get first day of current month
$num= 10; // how many past days you need from previous month + 1 (to remove current day)
for ($i=1; $i<$num; $i++) {
echo $prev= date('Y-m-d', strtotime(-$i.' day', strtotime($StartDate)))."<br />"; //get last days of previous month
}
?>
I am re writing it with your loop,
<?php
$dayCol = 0;
$leadInDays = 5; // (just for February cuz theres 5 blanks before its the 1st of Feb)
$StartDate= date("Y-F-d",strtotime("+0 Month"));
// Print last months' days spots.
for ($i=1; $i<($leadInDays+1); $i++) {
$lastmonth = date('d', strtotime(-$i.' day', strtotime($StartDate))); // Days in previous month
print "<td width=\"14%\" height=\"25%\" class=\"calendar_cell_disabled_middle\">$lastmonth</td>\n ";
$dayCol++;
}
?>
Test it Here
I would use date('t') to get the number of days in said month and just loop backwards:
$month = '2013-02-05';
for($i = date('t', strtotime($month)); $i > 0; $i--) {
...
}