I'm trying to go back one day in the calendar – What am I doing wrong?
My approach:
$weekdays = array('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun');
///////
function getDates($year) {
$dates = array();
date("L", mktime(0, 0, 0, 7, 7, $year)) ? $days = 366 : $days = 365;
///
for($i = 1; $i <= $days; $i++) {
// get Unix timestamp for a date
$month = date('F', mktime(0, 0, 0, 1, $i, $year));
$wk = date('W', mktime(0, 0, 0, 1, $i, $year));
$wkDay = date('D', mktime(0, 0, 0, 1, $i, $year));
$day = date('d', mktime(0, 0, 0, 1, $i, $year));
///
$dates[$month][$wk][$wkDay] = $day;
}
return $dates;
}
//////
$year = 2020; // from this Year
$dates = getDates($year);
$countW = 1; // for counting weeks
// Output code
echo '<h2><span>Calendar '.$year.'</span></h2>';
foreach($dates as $month => $weeks) {
echo '<div>';
echo '<table>';
echo '<caption>'.$year.' '.$month.'</caption>';
echo '<tr>';
echo '<th>W</th>';
echo '<th>'.implode('</th><th>', $weekdays).'</th>';
echo '</tr>';
echo '<tr>';
foreach ($weeks as $week => $days){
echo '<tr><td>'.$countW++.'</td>';
foreach ($weekdays as $day) {
echo '<td>';
/* I'm overwhelmed here! */
echo isset($days[$day]) ? $days[$day] : date('d', strtotime('-1 day')); // outputted is 5
echo '</td>';
}
echo '</tr>';
}
echo '</tr>';
echo '</table>';
}
I tried the following codes:
date('d', strtotime('-1 day')) // outputted: 5 (today is 6)
$jd = gregoriantojd(01,06,2020); echo jddayofweek($jd,2); // outputted: Mon (today is Tue)
With this code I get the day from the current day before.
It is expected the day before the specified day
what is happening
is expected
With this code I get the day from the current day before. It is expected the day before the specified day
The day that is "specified" here date('d', strtotime('-1 day')) is the current day.
Generally speaking, a (American) monthly calendar will leave a blank space if the day is not in the month. For example:
That would be a super simple fix to the problem. If not, you'll need to adjust your thinking (and the code!). In the case of the first week of January, the dates for Mon and Tues are -2 and -1 from the first day of January. Similarly, in the last week they are -2 and -1 from the first day of February (or +1, +2 from the last day of January).
Related
I am trying to build a loop that echoes each month of the year until the current month. My foreach loop just stays on the start and doesn't progress through the rest of the range. Here is my code:
$startMonth = '01';
$endMonth = date('m');
foreach (range($startMonth, $endMonth) as $month) {
$dataValue = date('n', $month);
echo '<td class="month" data-value="';
echo $dataValue;
echo '" data-id="' . $incrementYear . '"><a href="/Archive/view/';
echo $incrementYear;
echo '/';
echo date('m', $month);
echo '">';
echo date('F', $month);
echo '</a></td>';
}
Here is the output:
January January January January January January
Each of the months has the correct link for what January should have, but for some reason, the range never leaves "01" which is the $startMonth and I'm not sure why. I was thinking it had something to do with integer vs. string, but removing the ' from $startMonth = '01'; to make it an integer, but that didn't work either.
As far as I understand them, I am using the range correctly.
What am I missing here?
EDIT
$dataValue can be commented out and I will still get January 6 times, its just the link will have a data-value different than what I want. This variable has no effect on the month itself.
If I change the bottom line of code from echo date('F', $month); to echo $month; I get:
1 2 3 4 5 6
Problem is that to date() as timestamp you always pass 01, 02... and that converts to ~12 first seconds of Unix timestamp. So 1970-01-01 00:00:03 is January.
Change your code to use mktime
$dataValue = date('n', mktime(0, 0, 0, $month, 1, date('Y')));
$startMonth = '01';
$endMonth = date('m');
foreach (range($startMonth, $endMonth) as $month) {
$time = mktime(0, 0, 0, $month, 1, date('Y'));
$date = date('n', $time);
$month = date('m', $time);
$monthName = date('F', $time);
echo "<td class='month' data-value='{$date}' data-id='{$incrementYear}'><a href='/Archive/view/{$incrementYear}/{$month}'>{$monthName}</a></td>";
}
Try this:
$startMonth = '01';
$endMonth = date('m');
foreach (range($startMonth, $endMonth) as $month) {
$dataValue = date('F', mktime(0, 0, 0, $month, 1, date('Y')));
$month = sprintf('%02d', $month);
echo '<td class="month" data-value="' . $dataValue . '" data-id="' . $month . '">' . $dataValue . '</td>';
}
Output:
JanuaryFebruaryMarchAprilMayJune
Change the $dataValue from
$dataValue = date('n', $month);
to
$dateObj = DateTime::createFromFormat('!m', $month);
echo $dateObj->format('F');
Hope this helps.
Try Below Code:
$start_date = date('Y-01-01');
$end_date = date('Y-m-01');
$loop_date = $start_date;
//loop through months
while(strtotime($loop_date)<=strtotime($end_date)){
echo date('F',strtotime($loop_date));
$loop_date = date('Y-m-d', strtotime("+1 months", strtotime($loop_date)));
}
sorry if this is a duplicate. Why does the following code error so? It returns Dec 6th currently, the first Friday in December (asking on 8 Oct 2013)
$thisMonth = date('m');
$year = date("Y");
$thismonthName = date("M.", mktime(0, 0, 0, $thisMonth,0,$year));
if ($thisMonth < 12) {
$nextmonthName = date("M.", mktime(0, 0, 0, $nextMonth,1,$year));
} else {
$nextMonth = 1;
$nextmonthName = date("M.", mktime(0, 0, 0, $nextMonth,1,$nextYear));
}
$thisDate = date('M j', strtotime($nextmonthName . $year . "first friday"));
print ("second friday next month is " . $thisDate);
but modifying it to be only next month, like so,
$thisMonth = date('m');
$year = date("Y");
$thismonthName = date("M.", mktime(0, 0, 0, $thisMonth,0,$year));
if ($thisMonth < 12) {
$nextmonthName = date("M.", mktime(0, 0, 0, $nextMonth,0,$year));
} else {
$nextMonth = 1;
$nextmonthName = date("M.", mktime(0, 0, 0, $nextMonth,0,$nextYear));
}
$thisDate = date('M j', strtotime($nextmonthName . $year . "first friday"));
print ("second friday next month is " . $thisDate);
returns Nov 8th, the second Friday in November. Why is that?
You REALLY should investigate DateTime, DateInterval, DatePeriod classes. They make this sort of thing trivial.
$date = new DateTime();
$interval = DateInterval::createFromDateString('second friday of next month');
$date->add($interval);
echo 'Second Friday next month is ' . $date->format('Y-m-d');
Or to get 2nd Friday for next 3 months:
$date = new DateTime();
$recurrence_count = 3;
$interval = DateInterval::createFromDateString('second friday of next month');
$period = new DatePeriod($date, $interval, $recurrence_count);
foreach ($period as $dt) {
echo $dt->format('Y-m-d');
}
Your code is way too complicated.
$secondNextFriday = new DateTime('first friday of +2 months'); // First friday in december
I want a loop that checks the current month, 12 months in the future and 4 months in the past.
For example: Today is 1st August 08. My loop should go through April, May, June, July, August, September, October, November, December, January, February, March, April, May, June, July, and August.
I have tried strotime but I don't know how I can loop 4 months back and 12 months in the future.
Here is my code
$i = 1;
$month = strtotime('2013-08-01');
while($i <= 12) {
$month_name = date('F', $month);
echo $month_name;
echo "<br>";
$month = strtotime('+1 month', $month);
$i++;
I think Yoshi was almost there with his answer, but using DatePeriod with DateTime is more consistent and makes for more readable code IMHO:-
$oneMonth = new \DateInterval('P1M');
$startDate = \DateTime::createFromFormat('d H:i:s', '1 00:00:00')->sub(new \DateInterval('P4M'));
$period = new \DatePeriod($startDate, $oneMonth, 16);
foreach($period as $date){
//$date is an instance of \DateTime. I'm just var_dumping it for illustration
var_dump($date);
}
See it working
This can be quite tricky, here's how I would do it:
$month = date("n", "2013-08-01") - 1; // -1 to get 0-11 so we can do modulo
// since you want to go back 4 you can't just do $month - 4, use module trick:
$start_month = $month + 8 % 12;
// +8 % 12 is the same is -4 but without negative value issues
// 2 gives you: 2+8%12 = 10 and not -2
for ($i = 0; $i < 16; $i += 1) {
$cur_month = ($start_month + $i) % 12 + 1; // +1 to get 1-12 range back
$month_name = date('F Y', strtotime($cur_month . " months"));
var_dump(month_name);
}
something like this?:
$start = -4;
$end = 12;
for($i=$start; $i<=$end;$i++) {
$month_name = date('F Y', strtotime("$i months"));
echo $month_name;
echo "<br>";
}
Your code, just slightly modified.
date_default_timezone_set('UTC');
$i = 1;
$month = strtotime('-4 month');
while($i <= 16) {
$month_name = date('F', $month);
echo $month_name;
echo "<br>";
$month = strtotime('+1 month', $month);
$i++;
}
Simplest solution:
for($i=-4; $i<=12; $i++) {
echo date("F",strtotime( ($i > 0) ? "+$i months" : "$i months") )."\n";
}
Explanation:
The loop starts at -4 and goes all the way upto 12 (total 17, including 0). The ternary statement inside strtotime() simply checks if $i is positive, and if it is, a + is inserted so that we'll get the results for strtotime("+1 months") and similar.
Ta-da!
Using DateTime is the easiest and more readable way.
I would do it like this:
$from = new DateTime('-4 month');
$to = new DateTime('+12 month');
while($from < $to){
echo $from->modify('+1 month')->format('F');
}
I found this PHP code credit to creator and want to implement it a different way:
The goal is to have the code automatically adjust the following statement to be the second Saturday of every month from now until eternity:
Next membership meeting: Saturday, MONTH, DAY, YEAR, 11 a.m. to noon.
As in: "Saturday, February 12, 2011, 11 a.m. to noon."
I am no PHP guru, can someone kindly edit it to work?
<?php
function nextMeeting($nextMonth = false) {
$day=date("j");
$month=date("n");
$year=date("Y");
if ($nextMonth) {
$day=1;
if ($month == 12) {
$month=1;
$year++;
} else {
$month++;
}
}
$dayofweek=date("w");
$firstOfMonth=date("w",mktime(0, 0, 0, $month , 1, $year ));
// figure out what date is the second Saturday of the month
if ( $firstOfMonth > 0 ) {
$firstSunday= 8 - $firstOfMonth;
} else {
$firstSunday= 1;
}
$firstSundayDate=date("D",mktime(0, 0, 0, $month ,
$firstSunday, $year));
// figure out what date the third monday of the month is
if ( $firstOfMonth > 1) {
$offSet = 8 - $firstOfMonth;
} elseif ( $firstOfMonth == 0 ) {
$offSet=1;
} else {
$offSet=0;
}
$thirdMonday= 15 + $offSet;
$thirdMondayDate=date("D",mktime(0, 0, 0, $month ,
$thirdMonday, $year));
// lets see which of these dates now applies
if ($day <= $firstSunday) {
// we didn't miss the first meeting
$nextMeeting=$firstSunday;
$nextMeetingDate=mktime(0, 0, 0, $month ,
$nextMeeting, $year);
} elseif ( ($day > $firstSunday) && ($day <= $thirdMonday) ) {
// we missed the first meeting of the month, but can still make the second
$nextMeeting=$thirdMonday;
$nextMeetingDate=mktime(0, 0, 0, $month ,
$nextMeeting, $year);
} else {
// we need to wait until next month
$nextMeetingDate=nextMeeting(1);
$nextMeeting=nextMeeting(1);
}
return $nextMeetingDate;
}
$meeting=nextMeeting();
echo "Next membership meeting is on " . date('l dS \of F Y', $meeting);
?>
How about you save about 5000 lines and try this
<?
echo date('Y-m-d', strtotime('second saturday of february 2011'));
Edit
Ok, I lied in the comments, I will write it for you.
<?
$now=date("U");
$monthyear=date("F Y");
$secondsat=date('U', strtotime($monthyear.' second saturday'));
if ($now>$secondsat) {
$monthyear=date("F Y", "next month");
$secondsat=date('U', strtotime($monthyear.' second saturday'));
}
echo date("m/d/Y",$secondsat);
You could change the function a little like this:
function nextMeeting($date = null)
{
$day = date("j", $date);
$month = date("n", $date);
$year = date("Y", $date);
// remove the nextMonth bit
$dayofweek=date("w", $date);
$firstOfMonth=date("w",mktime(0, 0, 0, $month , 1, $year ));
// all the same between here and the end
return $nextMeetingDate;
}
for ($i = 0; $i < 12; $i++) {
$date = mktime(0, 0, 0, date('m') + $i, date('d'), date('y'));
echo "Next membership meeting is on " . date('l dS \of F Y', nextMeeting($date));
}
That should get you the next 12 meetings after today...
I needed to find the DTS date range, so here's how I did it:
$year = date("Y");
$dtsStart = date('Y-m-d 02:00:00', strtotime("Second Sunday Of March {$year}"));
$dtsEnd = date('Y-m-d 02:00:00', strtotime("First Sunday Of November {$year}"));
And of course you can replace the month with some simple coding as well.
I need to get the first and last day of a month in the format YYYY-MM-DD given only the month and year. Is there a good, easy way to do this?
$first = date('Y-m-d', mktime(0, 0, 0, $month, 1, $year));
$last = date('Y-m-t', mktime(0, 0, 0, $month, 1, $year));
See date() in PHP documentation.
First day is always YYYY-MM-01, isn't it? Example: date("Y-M-d", mktime(0, 0, 0, 8, 1, 2008))
Last day is the previous day of the next month's first day:
$date = new DateTime("2008-09-01");
$date->modify("-1 day");
echo $date->format("Y-m-d");
The first day of the month is always 1.
So it will become
YYYY-MM-01
the last day can be calculated as:
<?php
$num = cal_days_in_month(CAL_GREGORIAN, 8, 2003); // 31
echo "There was $num days in August 2003";
?>
OK, first is dead easy.
date ('Y-m-d', mktime(0,0,0,MM,01,YYYY));
Last is a little trickier, but not much.
date ('Y-m-d', mktime(0,0,0,MM + 1,-1,YYYY));
If I remember my PHP date stuff correctly...
**edit - Gah! Beaten to it about a million times...
Edit by Pat:
Last day should have been
date ('Y-m-d', mktime(0,0,0,$MM + 1,0,$YYYY)); // Day zero instead of -1
<?php
echo "Month Start - " . $monthStart = date("Y-m-1") . "<br/>";
$num = cal_days_in_month(CAL_GREGORIAN, date("m"), date("Y"));
echo "Monthe End - " . $monthEnd = date("Y-m-".$num);
?>
The easiest way to do this with PHP is
$dateBegin = strtotime("first day of last month");
$dateEnd = strtotime("last day of last month");
echo date("MYDATEFORMAT", $dateBegin);
echo "<br>";
echo date("MYDATEFORMAT", $dateEnd);
Or the last week
if (date('N', time()) == 7) {
$dateBegin = strtotime("-2 weeks Monday");
$dateEnd = strtotime("last Sunday");
} else {
$dateBegin = strtotime("Monday last week");
$dateEnd = strtotime("Sunday last week");
}
Or the last year
$dateBegin = strtotime("1/1 last year");
$dateEnd = strtotime("12/31 this year");
By the way #ZombieSheep solution
date ('Y-m-d', mktime(0,0,0,$MM + 1,-1,$YYYY));
does not work it should be
date ('Y-m-d', mktime(0,0,0,$MM + 1,0,$YYYY)); // Day zero instead of -1
Of course #Michał Słaby's accepted solution is the simplest.
Just to verify that I didn't miss any loose ends:
$startDay = 1;
if (date("m") == 1) {
$startMonth = 12;
$startYear = date("Y") - 1;
$endMonth = 12;
$endYear = date("Y") - 1;
}
else {
$startMonth = date("m") - 1;
$startYear = date("Y");
$endMonth = date("m") - 1;
$endYear = date("Y");
}
$endDay = date("d") - 1;
$startDate = date('Y-m-d', mktime(0, 0, 0, $startMonth , $startDay, $startYear));
$endDate = date('Y-m-d', mktime(0, 0, 0, $endMonth, $endDay, $endYear));
try this to get the number of days in the month:
$numdays = date('t', mktime(0, 0, 0, $m, 1, $Y));
Example; I want to get first day and last day of current month.
$month = (int) date('F');
$year = (int) date('Y');
date('Y-m-d', mktime(0, 0, 0, $month + 1, 1, $year)); //first
date('Y-m-d', mktime(0, 0, 0, $month + 2, 0, $year)); //last
When you run this for instance at date 2015-01-09, the first and last values will be sequentially;
2015-01-01
2015-01-31
Tested.
From here(get next month last day) that is marked as duplicated, so i can't add comment there, but people can got bad answers from there.
Correct one for last day of next month:
echo ((new DateTime(date('Y-m').'-01'))->modify('+1 month')->format('Y-m-t'));
Correct one for first day of next month:
echo ((new DateTime(date('Y-m').'-01'))->modify('+1 month')->format('Y-m-01'));
Code like this will be providing March from January, so that's not what could be expected.
echo ((new DateTime())->modify('+1 month')->format('Y-m-t'));
proper way to build a relative date from now is:
//bad example - will be broken when generated at 30 of December (broken February)
echo date("Y-m-d", strtotime("now"))."\n";
echo date("Y-m-d", strtotime("now + 1 month"))."\n";
echo date("Y-m-d", strtotime("now + 2 month"))."\n";
echo date("Y-m-d", strtotime("now + 3 month"))."\n";
//good example, you can change first day to last day or any day
echo date("Y-m-d", strtotime("first day of this month"))."\n";
echo date("Y-m-d", strtotime("first day of next month"))."\n";
echo date("Y-m-d", strtotime("first day of +2 month"))."\n";
echo date("Y-m-d", strtotime("first day of +3 month"))."\n";
and the result will be:
2021-12-30
2022-01-30
2022-03-02
2022-03-30
2021-12-01
2022-01-01
2022-02-01
2022-03-01