I need to include also the last Monday of the precedent month, and the first Monday of the next month.
Example
2016-01-25
2016-02-01
2016-02-08
2016-02-15
2016-02-22
2016-02-29
2016-03-07
I have this code so far:
function getAllDaysInAMonth($year, $month, $day = 'Monday', $daysError = 3) {
$dateString = 'first ' . $day . ' of ' . $year . '-' . $month;
if (!strtotime($dateString)) {
throw new \Exception('"' . $dateString . '" is not a valid strtotime');
}
$startDay = new \DateTime($dateString);
if ($startDay->format('j') > $daysError) {
$startDay->modify('- 7 days');
}
$days = array();
while ($startDay->format('Y-m') <= $year . '-' . str_pad($month, 2, 0, STR_PAD_LEFT)) {
$days[] = clone($startDay);
$startDay->modify('+ 7 days');
}
return $days;
}
Ok, resolved!
function getAllDaysInAMonth($year, $month, $day = 'Monday', $daysError = 3) {
$dateString = 'first ' . $day . ' of ' . $year . '-' . $month;
if (!strtotime($dateString)) {
throw new \Exception('"' . $dateString . '" is not a valid strtotime');
}
$startDay = new \DateTime($dateString);
if ($startDay->format('j') > $daysError) {
$startDay->modify('- 7 days');
}
$days = array();
$lastMonday = new DateTime("last Monday of last month");
$nextMonday = new DateTime("first Monday of next month");
$days[] = clone($lastMonday);
while ($startDay->format('Y-m') <= $year . '-' . str_pad($month, 2, 0, STR_PAD_LEFT)) {
$days[] = clone($startDay);
$startDay->modify('+ 7 days');
}
$days[] = clone($nextMonday);
return $days;
}
Try this :
$lastMonday = new DateTime("last Monday of last month");
$nextMonday = new DateTime("first Monday of next month");
echo 'Last Monday : '.$lastMonday->format('Y-m-d').'<br />';
echo 'First Monday : '.$nextMonday->format('Y-m-d');
Related
Here are the rules:
The adding of days is always by 15s (ex. 15, 30, 45, 60, etc.)
When the maturity date day falls on the 15th or end of the month
(ex. 30 or 31 depends on the month, 28 or 29 every February depends
if leap year) when adding days (as mention above) the date
should fall ONLY to 15th or end of month.
When the maturity date day does not fall every 15th or end of the
month just normally add days.
When the date is February 14 and add 15 days it should return 02/29 if leap year or 02/28 if not leap year.
Here is my code but, I am getting 1 error and inconsistency.
Catchable fatal error when the date is 02/29/2020 and add 30 days.
What can I do to accommodate this rules?
function adjustDate($maturitydate, $add) {
$nodays = '+'.$add.' days';
$date = new DateTime($maturitydate);
$matdt = $date->modify($nodays);
$ismaturitydateendofmonth = check_end_of_month($maturitydate);
if($date->format('d') == 15) {
$matdt = $matdt->format('m/15/Y');
}
else if($ismaturitydateendofmonth == '1'){
$matdt->modify('last day of this month');
}
else{
$matdt = $matdt->format('m/d/Y');
}
return $matdt;
}
function check_end_of_month($date){
//adds 1 day to date
$Temp = date('m/d/Y',strtotime("+1 day", strtotime($date)));
//get the month of each date
$tempmonth = date('m', strtotime($Temp));
$datemonth = date('m', strtotime($date));
//check if the months are equal
if($tempmonth != $datemonth){
return '1';
}
else{
return '0';
}
}
The code below will fix all the exceptions and inconsistencies.
$matdt = $maturitydatefrom;
for ($x = 0; $x < $chknumdif; $x++) {
$matdt = getNextDuedate($matdt, $maturitydatefrom);
}
function getNextDuedate($prevdate, $maturitydate){
$maturityday = date('d', strtotime($maturitydate));
$prevday = date('d', strtotime($prevdate));
$prevmonth = date('m', strtotime($prevdate));
$prevyear = date('Y', strtotime($prevdate));
$prevlastday = date('t', strtotime($prevdate));
$maturitylastday = date('t', strtotime($maturitydate));
$isendofmonth = check_end_of_month($maturitydate);
if($maturityday == $maturitylastday || $maturityday == 15){
if($prevday == 15){
$duedate = $prevmonth . '/' . $prevlastday . '/' . $prevyear;
}
else{
$prevdate = date('m/d/Y', strtotime("+1 month", strtotime($prevdate)));
$duedate = date('m', strtotime($prevdate)) . '/15/' . date('Y', strtotime($prevdate));
}
}
else{
if($prevday < 15){
if($prevmonth == '2' && $prevday == '14'){
$duedate = $prevmonth . '/' . $prevlastday . '/' . $prevyear;
}
else{
$duedate = $prevmonth . '/' . ($prevday + 15) . '/' . $prevyear;
}
}
else if($prevday > 15){
if($maturityday < 15){
$prevdate = date('m/d/Y', strtotime("+1 month", strtotime($prevdate)));
$duedate = date('m', strtotime($prevdate)) . '/' . $maturityday . '/' . date('Y', strtotime($prevdate));
}
else{
$prevdate = date('m/d/Y', strtotime("+1 month", strtotime($prevdate)));
$duedate = date('m', strtotime($prevdate)) . '/' . ($maturityday - 15) . '/' . date('Y', strtotime($prevdate));
}
}
}
return $duedate;
}
I have the year number (ex: 2018) and the month number (Ex:04). I want to get the starting date and the ending date for that month. like
2018-04-01 and 2018-04-30
try this
$year = 2018;
$month = 4;
$date_start = date('Y-m-d', strtotime(date($year.'-'.$month).' first day of this month'));
$date_end = date('Y-m-d', strtotime(date($year.'-'.$month).'last day of this month'));
echo $date_start . ' and ' . $date_end;
$months_array = $this->getting_particular_months_dates($start_day_of_year, $end_day_of_year);
$arra1=array();
foreach ($months_array as $K => $v)
{
$year=explode( '-',$v['month'])[1];
$month=explode( '-',$v['month'])[0];
$arra1[]=$this->get_month_dates((int)$year,(int)$month);
}
return $arra1;
public function getting_particular_months_dates($year_start_date, $year_end_date)
{
$month_array = array();
$date1 = $year_start_date;
$date2 = $year_end_date;
$output = [];
$time = strtotime($date1);
$last = date('m-Y', strtotime($date2));
do {
$month = date('m-Y', $time);
$total = date('t', $time);
$output[] = [
'month' => $month,
'total' => $total,
];
$time = strtotime('+1 month', $time);
} while ($month != $last);
$month_array = $output;
return $month_array;
}
public function get_month_dates($year, $month)
{
$date_start = date('Y-m-d', strtotime(date($year . '-' . $month) . ' first day of this month'));
$date_end = date('Y-m-d', strtotime(date($year . '-' . $month) . 'last day of this month'));
$a = array('first_day' => $date_start, 'last_day' => $date_end);
return $a;
}
I'm trying to list all months between two dates.
For example; start date is: 2010-12-02 and last date is: 2012-05-06
I want to list something like this:
2010-12
2011-01
2011-02
2011-03
2011-04
.
.
.
2012-04
2012-05
This is what I have tried and it is not working at all:
$year_min = 2010;
$year_max = 2012;
$month_min = 12;
$month_max = 5;
for($y=$year_min; $y<=$year_max; $y++)
{
for($m=$month_min; $m<=$month_max; $m++)
{
$period[] = $y.$m;
}
}
PHP 5.3
$start = new DateTime('2010-12-02');
$start->modify('first day of this month');
$end = new DateTime('2012-05-06');
$end->modify('first day of next month');
$interval = DateInterval::createFromDateString('1 month');
$period = new DatePeriod($start, $interval, $end);
foreach ($period as $dt) {
echo $dt->format("Y-m") . "<br>\n";
}
See it in action
PHP 5.4 or newer
$start = (new DateTime('2010-12-02'))->modify('first day of this month');
$end = (new DateTime('2012-05-06'))->modify('first day of next month');
$interval = DateInterval::createFromDateString('1 month');
$period = new DatePeriod($start, $interval, $end);
foreach ($period as $dt) {
echo $dt->format("Y-m") . "<br>\n";
}
The part where we modify the start and end dates to the first of the month is important. If we didn't, and the current day higher then the last day in February (i.e. 28 in non-leap years, 29 in leap years) this would skip February.
function getMonthsInRange($startDate, $endDate)
{
$months = array();
while (strtotime($startDate) <= strtotime($endDate)) {
$months[] = array(
'year' => date('Y', strtotime($startDate)),
'month' => date('m', strtotime($startDate)),
);
// Set date to 1 so that new month is returned as the month changes.
$startDate = date('01 M Y', strtotime($startDate . '+ 1 month'));
}
return $months;
}
You must make a difference between two months of the same year and two months of different years.
$year_min = substr($row['contractStart'], 0, 4);
$year_max = substr($row['contractEnd'], 0, 4);
$month_min = substr($row['contractStart'], 5, 2);
$month_min = substr($row['contractEnd'], 5, 2);
$period = array();
try {
if ($year_min > $year_max)
throw new Exception();
else if ($year_min == $year_max)
if ($month_min > $month_max)
throw new Exception();
for ($month = $month_min; $month <= $month_max; $month++) {
$period[] = $month . '-' . $year;
}
else {
for ($month = $month_min; $month <= 12; $month++) {
$period[] = $month . '-' . $year_min;
}
for ($year = $year_min + 1; $year < $year_max; $year++) {
for ($month = $month_min; $month <= $month_max; $month++) {
$period[] = $month . '-' . $year;
}
}
for ($month = 1; $month <= $month_max; $month++) {
$period[] = $month . '-' . $year_max;
}
}
implode("<br />\r\n", $period);
}
catch (Exception $e) {
echo 'Start date occurs after end date.'
}
That's for the hard way. Now there is a quick and easy way that is already given as an answer which I recommend you to choose.
This was my solution since DateTime is not available in my server environment.
$a = "2007-01-01";
$b = "2008-02-15";
$i = date("Ym", strtotime($a));
while($i <= date("Ym", strtotime($b))){
echo $i."\n";
if(substr($i, 4, 2) == "12")
$i = (date("Y", strtotime($i."01")) + 1)."01";
else
$i++;
}
Try it out: http://3v4l.org/BZOmb
In Laravel,
$period = \Carbon\CarbonPeriod::create('2017-06-28', '1 month', '2019-06-01');
foreach ($period as $dt) {
echo $dt->format("Y-m") . "<br>\n";
}
October 2021 Update
If you have dates selected by the user, here's a solution
$from = date('Y-m-d', strtotime($_POST['from']));
$to = date('Y-m-d', strtotime($_POST['to']));
$counter = 1;
$max_date = strtotime($to);
$current_date = strtotime($from);
$dates = [];
$months = [];
$loop = true;
while($loop) {
if(strtotime(date('Y-m-d',$current_date)." +".$counter."days") >= $max_date) $loop = false;
else {
$current_date = strtotime(date('Y-m-d', $current_date)." +".$counter."days");
$date = date('Y-m-d', $current_date);
$dates[] = $date;
$months[] = date('Y-m', $current_date);
$counter++;
}
}
$months = array_unique($months);
echo '<pre>';
print_r($dates);
echo '<br>';
print_r($months);
echo '</pre>';
I'm trying to list all months between two dates.
For example; start date is: 2010-12-02 and last date is: 2012-05-06
I want to list something like this:
2010-12
2011-01
2011-02
2011-03
2011-04
.
.
.
2012-04
2012-05
This is what I have tried and it is not working at all:
$year_min = 2010;
$year_max = 2012;
$month_min = 12;
$month_max = 5;
for($y=$year_min; $y<=$year_max; $y++)
{
for($m=$month_min; $m<=$month_max; $m++)
{
$period[] = $y.$m;
}
}
PHP 5.3
$start = new DateTime('2010-12-02');
$start->modify('first day of this month');
$end = new DateTime('2012-05-06');
$end->modify('first day of next month');
$interval = DateInterval::createFromDateString('1 month');
$period = new DatePeriod($start, $interval, $end);
foreach ($period as $dt) {
echo $dt->format("Y-m") . "<br>\n";
}
See it in action
PHP 5.4 or newer
$start = (new DateTime('2010-12-02'))->modify('first day of this month');
$end = (new DateTime('2012-05-06'))->modify('first day of next month');
$interval = DateInterval::createFromDateString('1 month');
$period = new DatePeriod($start, $interval, $end);
foreach ($period as $dt) {
echo $dt->format("Y-m") . "<br>\n";
}
The part where we modify the start and end dates to the first of the month is important. If we didn't, and the current day higher then the last day in February (i.e. 28 in non-leap years, 29 in leap years) this would skip February.
function getMonthsInRange($startDate, $endDate)
{
$months = array();
while (strtotime($startDate) <= strtotime($endDate)) {
$months[] = array(
'year' => date('Y', strtotime($startDate)),
'month' => date('m', strtotime($startDate)),
);
// Set date to 1 so that new month is returned as the month changes.
$startDate = date('01 M Y', strtotime($startDate . '+ 1 month'));
}
return $months;
}
You must make a difference between two months of the same year and two months of different years.
$year_min = substr($row['contractStart'], 0, 4);
$year_max = substr($row['contractEnd'], 0, 4);
$month_min = substr($row['contractStart'], 5, 2);
$month_min = substr($row['contractEnd'], 5, 2);
$period = array();
try {
if ($year_min > $year_max)
throw new Exception();
else if ($year_min == $year_max)
if ($month_min > $month_max)
throw new Exception();
for ($month = $month_min; $month <= $month_max; $month++) {
$period[] = $month . '-' . $year;
}
else {
for ($month = $month_min; $month <= 12; $month++) {
$period[] = $month . '-' . $year_min;
}
for ($year = $year_min + 1; $year < $year_max; $year++) {
for ($month = $month_min; $month <= $month_max; $month++) {
$period[] = $month . '-' . $year;
}
}
for ($month = 1; $month <= $month_max; $month++) {
$period[] = $month . '-' . $year_max;
}
}
implode("<br />\r\n", $period);
}
catch (Exception $e) {
echo 'Start date occurs after end date.'
}
That's for the hard way. Now there is a quick and easy way that is already given as an answer which I recommend you to choose.
This was my solution since DateTime is not available in my server environment.
$a = "2007-01-01";
$b = "2008-02-15";
$i = date("Ym", strtotime($a));
while($i <= date("Ym", strtotime($b))){
echo $i."\n";
if(substr($i, 4, 2) == "12")
$i = (date("Y", strtotime($i."01")) + 1)."01";
else
$i++;
}
Try it out: http://3v4l.org/BZOmb
In Laravel,
$period = \Carbon\CarbonPeriod::create('2017-06-28', '1 month', '2019-06-01');
foreach ($period as $dt) {
echo $dt->format("Y-m") . "<br>\n";
}
October 2021 Update
If you have dates selected by the user, here's a solution
$from = date('Y-m-d', strtotime($_POST['from']));
$to = date('Y-m-d', strtotime($_POST['to']));
$counter = 1;
$max_date = strtotime($to);
$current_date = strtotime($from);
$dates = [];
$months = [];
$loop = true;
while($loop) {
if(strtotime(date('Y-m-d',$current_date)." +".$counter."days") >= $max_date) $loop = false;
else {
$current_date = strtotime(date('Y-m-d', $current_date)." +".$counter."days");
$date = date('Y-m-d', $current_date);
$dates[] = $date;
$months[] = date('Y-m', $current_date);
$counter++;
}
}
$months = array_unique($months);
echo '<pre>';
print_r($dates);
echo '<br>';
print_r($months);
echo '</pre>';
I'm trying to list all months between two dates.
For example; start date is: 2010-12-02 and last date is: 2012-05-06
I want to list something like this:
2010-12
2011-01
2011-02
2011-03
2011-04
.
.
.
2012-04
2012-05
This is what I have tried and it is not working at all:
$year_min = 2010;
$year_max = 2012;
$month_min = 12;
$month_max = 5;
for($y=$year_min; $y<=$year_max; $y++)
{
for($m=$month_min; $m<=$month_max; $m++)
{
$period[] = $y.$m;
}
}
PHP 5.3
$start = new DateTime('2010-12-02');
$start->modify('first day of this month');
$end = new DateTime('2012-05-06');
$end->modify('first day of next month');
$interval = DateInterval::createFromDateString('1 month');
$period = new DatePeriod($start, $interval, $end);
foreach ($period as $dt) {
echo $dt->format("Y-m") . "<br>\n";
}
See it in action
PHP 5.4 or newer
$start = (new DateTime('2010-12-02'))->modify('first day of this month');
$end = (new DateTime('2012-05-06'))->modify('first day of next month');
$interval = DateInterval::createFromDateString('1 month');
$period = new DatePeriod($start, $interval, $end);
foreach ($period as $dt) {
echo $dt->format("Y-m") . "<br>\n";
}
The part where we modify the start and end dates to the first of the month is important. If we didn't, and the current day higher then the last day in February (i.e. 28 in non-leap years, 29 in leap years) this would skip February.
function getMonthsInRange($startDate, $endDate)
{
$months = array();
while (strtotime($startDate) <= strtotime($endDate)) {
$months[] = array(
'year' => date('Y', strtotime($startDate)),
'month' => date('m', strtotime($startDate)),
);
// Set date to 1 so that new month is returned as the month changes.
$startDate = date('01 M Y', strtotime($startDate . '+ 1 month'));
}
return $months;
}
You must make a difference between two months of the same year and two months of different years.
$year_min = substr($row['contractStart'], 0, 4);
$year_max = substr($row['contractEnd'], 0, 4);
$month_min = substr($row['contractStart'], 5, 2);
$month_min = substr($row['contractEnd'], 5, 2);
$period = array();
try {
if ($year_min > $year_max)
throw new Exception();
else if ($year_min == $year_max)
if ($month_min > $month_max)
throw new Exception();
for ($month = $month_min; $month <= $month_max; $month++) {
$period[] = $month . '-' . $year;
}
else {
for ($month = $month_min; $month <= 12; $month++) {
$period[] = $month . '-' . $year_min;
}
for ($year = $year_min + 1; $year < $year_max; $year++) {
for ($month = $month_min; $month <= $month_max; $month++) {
$period[] = $month . '-' . $year;
}
}
for ($month = 1; $month <= $month_max; $month++) {
$period[] = $month . '-' . $year_max;
}
}
implode("<br />\r\n", $period);
}
catch (Exception $e) {
echo 'Start date occurs after end date.'
}
That's for the hard way. Now there is a quick and easy way that is already given as an answer which I recommend you to choose.
This was my solution since DateTime is not available in my server environment.
$a = "2007-01-01";
$b = "2008-02-15";
$i = date("Ym", strtotime($a));
while($i <= date("Ym", strtotime($b))){
echo $i."\n";
if(substr($i, 4, 2) == "12")
$i = (date("Y", strtotime($i."01")) + 1)."01";
else
$i++;
}
Try it out: http://3v4l.org/BZOmb
In Laravel,
$period = \Carbon\CarbonPeriod::create('2017-06-28', '1 month', '2019-06-01');
foreach ($period as $dt) {
echo $dt->format("Y-m") . "<br>\n";
}
October 2021 Update
If you have dates selected by the user, here's a solution
$from = date('Y-m-d', strtotime($_POST['from']));
$to = date('Y-m-d', strtotime($_POST['to']));
$counter = 1;
$max_date = strtotime($to);
$current_date = strtotime($from);
$dates = [];
$months = [];
$loop = true;
while($loop) {
if(strtotime(date('Y-m-d',$current_date)." +".$counter."days") >= $max_date) $loop = false;
else {
$current_date = strtotime(date('Y-m-d', $current_date)." +".$counter."days");
$date = date('Y-m-d', $current_date);
$dates[] = $date;
$months[] = date('Y-m', $current_date);
$counter++;
}
}
$months = array_unique($months);
echo '<pre>';
print_r($dates);
echo '<br>';
print_r($months);
echo '</pre>';