I want to create a table like this...
Oct-01 | Oct-02 | Oct-03 | Oct-04 | etc etc
Using whatever month it is now.
I'm using this to get the first day...
$first = date('01-m-Y',strtotime('this month'));
How can I increment this by the amount of days in this month?
Use cal_days_in_month(CAL_GREGORIAN, date(j), 2013)?
But how to increment the first day.
I tried using '+1 day' in the strtotime, but nothing happened.
Any ideas?
PHP's DateTime class can be used here. You don't need to use cal_days_in_month function to calculate the number of days in a month -- DateTime handles it automatigically. And it's a lot more cleaner and supports a wide range of dates.
Here's how:
$start = new DateTime('first day of this month');
$end = new DateTime('first day of this month + 1 month');
$period = new DatePeriod($start, new DateInterval('P1D'), $end);
foreach($period as $day){
echo $day->format('M-d')."<br/>";
}
Demo!
I prefer using the DateTime object:
$date = new DateTime();
$date->modify('first day of this month');
$days = array();
for($i = 1; $i <= $date->format('t'); $i++){
$days[] = $date->format('M-d');
$date->modify('+1 day');
}
You could also add the whole date object to the array giving you flexibility later to use it however you want.
<?php
$days = array();
$maxDay = cal_days_in_month(CAL_GREGORIAN, date('j'), date('Y'));
for($i = 1; $i<$maxDay; ++$i) {
$days[] = sprintf(date('M')."-%1$02d", $i);
}
echo "<pre>";
var_dump($days);
Now you can do whatever you like with $days array...
http://phpfiddle.org/lite/code/fd1-1r2
Related
My Issue:
I have found a way to select every other Wednesday here: PHP Select every other Wednesday with the following code.
<?php
$number_of_dates = 10;
$start_date = new DateTime("1/1/20");
$interval = DateInterval::createFromDateString("second wednesday");
$period = new DatePeriod($start_date, $interval, $number_of_dates - 1);
foreach ($period as $date) {
$datex = $date->format("m-d-Y").PHP_EOL;
echo "$datex<br>";
}
?>
What I need to do is put every other Wednesday into an array.
I can put a range of dates into an array, but it uses every day in the range with the following code. I just need it to be every other Wednesday. How can I do this?
<?PHP
$dates = array();
$datetime1 = new DateTime("2020-01-01");
$datetime2 = new DateTime("2020-1-31");
$interval = $datetime1->diff($datetime2);
$days = (int) $interval->format('%R%a');
$currentTimestamp = $datetime1->getTimestamp();
$dates[] = date("m/d/Y", $currentTimestamp);
for ($x = 0; $x < $days; $x++)
{
$currentTimestamp = strtotime("+1 day", $currentTimestamp);
$dates[] = date("m/d/Y", $currentTimestamp);
}
print_r($dates);
?>
Try this :
<?php
$dates = array();
$datetime = new DateTime();
for ($i = 0; $i < 52; $i++) {
$datetime->modify('next Wednesday');
array_push($dates, $datetime->format('m/d/Y'));
}
print_r($dates);
What does it do ?
it gets the current time (you can customize this in the new
Datetime),
then loops for 52 times (you can customize this too in the for loop),
then finds the next wednesday using modify.
Live Demo :
http://sandbox.onlinephpfunctions.com/code/57c6a6b682a07f75bc1c507c588c844d84330610
Regards
Your first snippet is already outputting the right set of dates, so you just would need to put each of those in an array, instead of echoing them.
(Although I don't know if it's really necessary to do so, since you can already loop over the $period variable - but it depends exactly what you plan to do with the data afterwards).
Example:
$number_of_dates = 10;
$start_date = new DateTime("1/1/20");
$interval = DateInterval::createFromDateString("second wednesday");
$period = new DatePeriod($start_date, $interval, $number_of_dates - 1);
$dates = array(); //declare a new empty array
foreach ($period as $date) {
$dates[] = $date; //add the date to the next empty array index
}
var_dump($dates);
Or if you actually want an array containing the string representations of those dates, in that specific format, then:
$dates2 = array();
foreach ($period as $date) {
$dates2[] = $date->format("m-d-Y");
}
var_dump($dates2);
Live demo: http://sandbox.onlinephpfunctions.com/code/9e58e552edff204ae6df3ca9b437b8c597edf2b3
Give it a try
<?PHP
$dates = [];
$datetime1 = new DateTime("2020-01-01");
$datetime2 = new DateTime("2020-01-31");
$datetime1->modify('wednesday'); // Start with wednesday
while($datetime1 < $datetime2){
$dates[] = $datetime1->format('Y-m-d');
$datetime1->modify('second wednesday'); // Other Wednesday
}
print_r($dates);
?>
I'm searching for the best way to echo day numbers in a week.
First i need to check what week there is.
And then echo all dates of the week into variables.
This is what i got:
//This Week Variable dates
$this_year = date('Y');
$this_week_no = date('W');
$this_week_mon = new DateTime();
$this_week_mon->setISODate($this_year,$this_week_no);
How do i rise tue by one day?
$this_week_tue = $this_week_mon ++;
You can use DateTime::modify():
$this_week_mon->modify('+1 day');
or DateTime::add() which accepts a DateInterval() object:
$this_week_mon->add(new DateInterval('P1D'));
You can loop through all of the days of the week using DatePeriod():
$start = new DateTime();
$start->setISODate($this_year,$this_week_no);
$end = clone $start;
$end->modify('+1 week');
$interval = new DateInterval('P1D');
$period = new DatePeriod($start, $interval, $end);
foreach ($period as $date) {
echo $date->format('N');
}
$this_week_mon->modify('+1 day');
Should increment $this_week_mon by one day. To increase by more, just use days;
$this_week_mon->modify('+27 day');
Would increment by 27 days.
I'd like to work with PHP DateInterval to iterate through months:
$from = new DateTime();
$from->setDate(2014, 1, 31);
$period = new DatePeriod($from, new DateInterval('P1M'), 12);
I'd expect it to returns 31 January, 28 February (as the DateInterval is 1 month), but it actually returns 31 January, 3 March, 3 of April... hence skipping February.
Is there any way to do this simply?
Thanks!
EDIT : as a refernece, here is a solution that seems to cover most use cases:
$date = new DateTime('2014-01-31');
$start = $date->format('n');
for ($i = 0; $i < 28; $i++) {
$current = clone $date;
$current->modify('+'.$i.' month');
if ($current->format('n') > ($start % 12) && $start !== 12) {
$current->modify('last day of last month');
}
$start++;
echo $current->format('Y-m-d').PHP_EOL;
}
You can use DateTime::modify():
$date = new DateTime('last day of january');
echo $date->format('Y-m-d').PHP_EOL;
for ($i = 1; $i < 12; $i++) {
$date->modify('last day of next month');
echo $date->format('Y-m-d').PHP_EOL;
}
EDIT: I think I didn't understand your question clearly. Here is a new version:
$date = new DateTime('2014-01-31');
for ($i = 0; $i < 12; $i++) {
$current = clone $date;
$current->modify('+'.$i.' month');
if ($current->format('n') > $i + 1) {
$current->modify('last day of last month');
}
echo $current->format('Y-m-d').PHP_EOL;
}
The issue is cause by the variance between the last day in each of the months within the range. ie. February ending on 28 instead of 31 and the addition of 1 month from the last day 2014-01-31 + 1 month = 2014-03-03 https://3v4l.org/Y42QJ
To resolve the issue with DatePeriod and simplify it a bit, adjust the initial date by resetting the specified date to the first day of the specified month, by using first day of this month.
Then during iteration, you can modify the date period date by using last day of this month to retrieve the bounds of the currently iterated month.
Example: https://3v4l.org/889mB
$from = new DateTime('2014-01-31');
$from->modify('first day of this month'); //2014-01-01
$period = new DatePeriod($from, new DateInterval('P1M'), 12);
foreach ($period as $date) {
echo $date->modify('last day of this month')->format('Y-m-d');
}
Result:
2014-01-31
2014-02-28
2014-03-31
2014-04-30
2014-05-31
2014-06-30
2014-07-31
2014-08-31
2014-09-30
2014-10-31
2014-11-30
2014-12-31
2015-01-31
Then to expand on this approach, in order to retrieve the desired day from the specified date, such as the 29th. You can extract the specified day and adjust the currently iterated month as needed when the day is out of bounds for that month.
Example: https://3v4l.org/SlEJc
$from = new DateTime('2014-01-29');
$day = $from->format('j');
$from->modify('first day of this month'); //2014-01-01
$period = new DatePeriod($from, new DateInterval('P1M'), 12);
foreach ($period as $date) {
$lastDay = clone $date;
$lastDay->modify('last day of this month');
$date->setDate($date->format('Y'), $date->format('n'), $day);
if ($date > $lastDay) {
$date = $lastDay;
}
echo $date->format('Y-m-d');
}
Result:
2014-01-29
2014-02-28 #notice the last day of february is used
2014-03-29
2014-04-29
2014-05-29
2014-06-29
2014-07-29
2014-08-29
2014-09-29
2014-10-29
2014-11-29
2014-12-29
2015-01-29
You may try like this:
$date = new DateTime();
$lastDayOfMonth = $date->modify(
sprintf('+%d days', $date->format('t') - $date->format('j'))
);
I would do it probably like this
$max = array (
31,28,31,30,31,30,31,31,30,31,30,31
); //days in month
$month = 1;
$year = 2014;
$day = 31;
$iterate = 12;
$dates = array();
for ($i = 0;$i < $iterate;$i++) {
$tmp_month = ($month + $i) % 12;
$tmp_year = $year + floor($month+$i)/12;
$tmp_day = min($day, $max[$tmp_month]);
$tmp = new DateTime();
$tmp->setDate($tmp_year, $tmp_month + 1, $tmp_day);
$dates[] = $tmp;
}
var_dump($dates);
This keeps to the same day each month if possible
What's the cleanest way to use a loop in PHP to list dates in the following way?
2011_10
2011_09
2011_08
2011_07
2011_06
...
2010_03
2009_02
2009_01
2009_12
2009_11
The key elements here:
Should be as simple as possible - I would prefer one for loop instead of two.
Should list this month's date as the first date, and should stop at a fixed point (2009-11)
Should not break in the future (eg: subtracting 30 days worth of seconds will probably work but will eventually break as there are not an exact amount of seconds on each month)
Had to make a few tweaks to the solution:
// Set timezone
date_default_timezone_set('UTC');
// Start date
$date = date('Y').'-'.date('m').'-01';
// End date
$end_date = '2009-1-1';
while (strtotime($date) >= strtotime($end_date))
{
$date = date ("Y-m-d", strtotime("-1 month", strtotime($date)));
echo substr($date,0,7);
echo "\n";
}
Maybe this little code does the thing? :
more complicated situations.
<?php
// Set timezone
date_default_timezone_set('UTC');
// Start date
$date = '2009-12-06';
// End date
$end_date = '2020-12-31';
while (strtotime($date) <= strtotime($end_date)) {
echo "$date\n";
$date = date ("Y-m-d", strtotime("+1 day", strtotime($date)));
}
?>
The credit goes to: http://www.if-not-true-then-false.com/2009/php-loop-through-dates-from-date-to-date-with-strtotime-function/
This is what im guessing your asking for cause it doesnt really make sense......
$startmonth = date("m");
$endmonth = 7;
$startyear = date("Y");
$endyear = 2012;
//First for loop to loop threw years
for($i=$startyear; $i<=$endyear; $i++, $startmonth=0) {
//Second for loop to loop threw months
for($o=$startmonth; $o<=12; $o++) {
//If statement to check and throw stop when at limits
if($i == $endyear && $o <= $endmonth)
echo $i."_".$o."<br/>";
else
break;
}
}
Will output:
2012_0
2012_1
2012_2
2012_3
2012_4
2012_5
2012_6
2012_7
PHP 5.3 introduces some great improvements to date/time processing in PHP. For example, the first day of, DateInterval and DatePeriod being used below.
$start = new DateTime('first day of this month');
$end = new DateTime('2009-11-01');
$interval = new DateInterval('P1M');
$period = new DatePeriod($start, $interval, $end);
foreach ($period as $date) {
echo $date->format('Y_m') . PHP_EOL;
}
Let's assume I have two dates in variables, like
$date1 = "2009-09-01";
$date2 = "2010-05-01";
I need to get the count of months between $date2 and $date1($date2 >= $date1). I.e. i need to get 8.
Is there a way to get it by using date function, or I have to explode my strings and do required calculations?
Thanks.
For PHP >= 5.3
$d1 = new DateTime("2009-09-01");
$d2 = new DateTime("2010-05-01");
var_dump($d1->diff($d2)->m); // int(4)
var_dump($d1->diff($d2)->m + ($d1->diff($d2)->y*12)); // int(8)
DateTime::diff returns a DateInterval object
If you don't run with PHP 5.3 or higher, I guess you'll have to use unix timestamps :
$d1 = "2009-09-01";
$d2 = "2010-05-01";
echo (int)abs((strtotime($d1) - strtotime($d2))/(60*60*24*30)); // 8
But it's not very precise (there isn't always 30 days per month).
Last thing : if those dates come from your database, then use your DBMS to do this job, not PHP.
Edit: This code should be more precise if you can't use DateTime::diff or your RDBMS :
$d1 = strtotime("2009-09-01");
$d2 = strtotime("2010-05-01");
$min_date = min($d1, $d2);
$max_date = max($d1, $d2);
$i = 0;
while (($min_date = strtotime("+1 MONTH", $min_date)) <= $max_date) {
$i++;
}
echo $i; // 8
Or, if you want the procedural style:
$date1 = new DateTime("2009-09-01");
$date2 = new DateTime("2010-05-01");
$interval = date_diff($date1, $date2);
echo $interval->m + ($interval->y * 12) . ' months';
UPDATE: Added the bit of code to account for the years.
Or a simple calculation would give :
$numberOfMonths = abs((date('Y', $endDate) - date('Y', $startDate))*12 + (date('m', $endDate) - date('m', $startDate)))+1;
Accurate and works in all cases.
This is another way to get the number of months between two dates:
// Set dates
$dateIni = '2014-07-01';
$dateFin = '2016-07-01';
// Get year and month of initial date (From)
$yearIni = date("Y", strtotime($dateIni));
$monthIni = date("m", strtotime($dateIni));
// Get year an month of finish date (To)
$yearFin = date("Y", strtotime($dateFin));
$monthFin = date("m", strtotime($dateFin));
// Checking if both dates are some year
if ($yearIni == $yearFin) {
$numberOfMonths = ($monthFin-$monthIni) + 1;
} else {
$numberOfMonths = ((($yearFin - $yearIni) * 12) - $monthIni) + 1 + $monthFin;
}
I use this:
$d1 = new DateTime("2009-09-01");
$d2 = new DateTime("2010-09-01");
$months = 0;
$d1->add(new \DateInterval('P1M'));
while ($d1 <= $d2){
$months ++;
$d1->add(new \DateInterval('P1M'));
}
print_r($months);
Using DateTime, this will give you a more accurate solution for any amount of months:
$d1 = new DateTime("2011-05-14");
$d2 = new DateTime();
$d3 = $d1->diff($d2);
$d4 = ($d3->y*12)+$d3->m;
echo $d4;
You would still need to handle the leftover days $d3->d if your real world problem is not as simple and cut and dry as the original question where both dates are on the first of the month.
This is a simple method I wrote in my class to count the number of months involved into two given dates :
public function nb_mois($date1, $date2)
{
$begin = new DateTime( $date1 );
$end = new DateTime( $date2 );
$end = $end->modify( '+1 month' );
$interval = DateInterval::createFromDateString('1 month');
$period = new DatePeriod($begin, $interval, $end);
$counter = 0;
foreach($period as $dt) {
$counter++;
}
return $counter;
}
In case the dates are part of a resultset from a mySQL query, it is much easier to use the TIMESTAMPDIFF function for your date calculations and you can specify return units eg. Select TIMESTAMPDIFF(MONTH, start_date, end_date)months_diff from table_name
strtotime is not very precise, it makes an approximate count, it does not take into account the actual days of the month.
it's better to bring the dates to a day that is always present in every month.
$date1 = "2009-09-01";
$date2 = "2010-05-01";
$d1 = mktime(0, 0, 1, date('m', strtotime($date1)), 1, date('Y', strtotime($date1)));
$d2 = mktime(0, 0, 1, date('m', strtotime($date2)), 1, date('Y', strtotime($date2)));
$total_month = 0;
while (($d1 = strtotime("+1 MONTH", $d1)) <= $d2) {
$total_month++;
}
echo $total_month;
I have used this and works in all conditions
$fiscal_year = mysql_fetch_row(mysql_query("SELECT begin,end,closed FROM fiscal_year WHERE id = '2'"));
$date1 = $fiscal_year['begin'];
$date2 = $fiscal_year['end'];
$ts1 = strtotime($date1);
$ts2 = strtotime($date2);
$te=date('m',$ts2-$ts1);
echo $te;