Calculating and adjusting dates based on exceptions (PHP) - php

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;
}

Related

How-to get the start/end Mondays of the month in php

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');

Date changing in loop

Hi I've created an array that has a Start Date that increases by a month and this happens by how many months there are. So if my StartDate was 10/10/15 and placed 3 into my for loop I would receive 10/10/15 10/11/15 10/12/15 10/01/16. My current problem is that I've added a new while loop to find out if some of the days of the months fall on either a Saturday or Sunday.Which I don't want I would like it to fall on a weekday. So ive created this loop and it works however I have another problem. If 10/11/15 fell on a Sunday my loop will change it to 11/11/15 Monday which is correct but the rest of dates after it will now follow the changed date example be 11/12/15, 11/01/16.
I want it change the date but still the other dates to still increase from the startdate (10/10/15) like 10/10/15, 11/11/15, 10/12/15, 10/01/16. How would I do this? I also understand some of my code may not be the best but I am just a beginner. Any help would be much appreciated.
$date = "2015-10-1"; //startdate
$lol = 2; //length of loan
$start = strtotime($date); //startdate
$currentdate = $start;
echo "<pre>";
$times_table = [];
$titles[] = [
'Version' => 'Version 5 ',
'Date' => 'Feb-16',
'Name' => 'gary',
'RandNum' => '80',
'PaymentType' => 'P',
'dtType' => 'Q',
];
$times_table = [];
for($i = 0; $i <= ($lol + 1) ; $i++){
$times_table[$i]['StartDate']= $date ;
$times_table[$i]['Version']= "v10" ;
$cur_date = date("M-y-D", $currentdate);
$times_table[$i]['DtMy']= "<strong>" . $cur_date . "</strong>" ;
$mthYr = date("M", $currentdate);
$nxtmth = " ";
// Loop that changes the day to a weekday
while($nxtmth != "Y" ) {
if( $cur_date = date("M", $currentdate) !== $mthYr){
$nxtmth = "Y";
$currentdate = strtotime('-1 days', $currentdate);
$cur_date = date("d-M", $currentdate);
$times_table[$i]['DtMy']= "<strong>" . $cur_date . "</strong>" ;
}
if ($cur_date = date("w", $currentdate) == 0 || $cur_date = date("w", $currentdate) == 6){
if ($nxtmth == "Y"){
$currentdate = strtotime('-1 day', $currentdate);
$cur_date = date("d-M", $currentdate);
$times_table[$i]['DtMy']= "<strong>" . $cur_date . "</strong>" ;
}
else{
$currentdate = strtotime('+1 day', $currentdate);
$cur_date = date("d-M", $currentdate);
$times_table[$i]['DtMy']= "<strong>" . $cur_date . "</strong>" ;
}
if(($cur_date = date("M", $currentdate)) !== $mthYr){
$nxtmth = "Y";
$currentdate = strtotime('-1 day', $currentdate);
$cur_date = date("d-M", $currentdate);
$times_table[$i]['DtMy']= "<strong>" . $cur_date . "</strong>" ;
}
}
if($cur_date = date("w", $currentdate) > 0 && $cur_date = date("w", $currentdate) < 6 ){
$cur_date = date("d-M", $currentdate);
$times_table[$i]['DtMy']= "<strong>" . $cur_date . "</strong>" ;
break;
}
}
$currentdate = strtotime('+1 month', $currentdate); //Adds 1 month
}
print_r($times_table);
echo "</ pre>";
You can simply store the value in temp variable before overwriting
<?php
$date = "2015-10-1"; //startdate
$lol = 2; //length of loan
$dates = [];
for($i = 0; $i <= ($lol + 1) ; $i++){
$rawDate = strtotime($date);
$tmpRawDate = $rawDate;
$day = date('N', $rawDate);
// check if date is sat or sun
if($day == 6 || $day == 7)
$rawDate = strtotime($date . ' +'.(8 - $day).' day');
$dates[] = date('Y-m-d', $rawDate);
$rawDate = $tmpRawDate;
$rawDate = strtotime($date . ' +1 month');
$date = date('Y-m-d', $rawDate);
}
echo '<pre>';
print_r($dates);
Demo: https://eval.in/494664
UPDATE
<?php
$date = "2015-10-1"; //startdate
$lol = 2; //length of loan
$start = strtotime($date); //startdate
$currentdate = $start;
echo "<pre>";
$titles[] = [
'Version' => 'Version 5 ',
'Date' => 'Feb-16',
'Name' => 'gary',
'RandNum' => '80',
'PaymentType' => 'P',
'dtType' => 'Q',
];
$times_table = [];
for($i = 0; $i <= ($lol + 1) ; $i++){
// store the start date in tmp variable.
$tmpStart = $start;
// get the day counter 0 for monday .. 6 for sunday
$day = date('N', $start);
$times_table[$i]['StartDate']=$date;
$times_table[$i]['Version']="v10";
// check for sat and sun, if found increment to next monday
if($day == 6 || $day == 7)
$start = strtotime(' +'.(8 - $day).' day', $start);
$times_table[$i]['DtMy']= "<strong>" . date("d-M", $start) . "</strong>";
// restore the original variable
$start = $tmpStart;
// Increment one month
$start = strtotime('+1 month', $start);
}
print_r($times_table);

Get the same specific date on each month of the whole year

I am working on a "cut-off" date and I need to set it on every month. Say, I set the cut-off date to August 25 for this year, then it should be September 25, October 25 and so on till the year ends.
Here's the code I have:
$now = "2015-08-25";
$nextDate = getCutoffDate($now);
echo $nextDate;
function getCutoffDate($start_date)
{
$date_array = explode("-",$start_date); // split the array
// var_dump($date_array);
$year = $date_array[0];
$month = $date_array[1];
$day = $date_array[2];
/*if (date('n', $now)==12)
{
return date("Y-m-d",strtotime(date("Y-m-d", $start_date) . "+1 month"));
}*/
if (date("d") <= $day) {
$billMonth = date_format(date_create(), 'm');
}
else{
$billMonth = date_format(date_modify(date_create(), 'first day of next month'), 'm');
}
// echo date("d").' '. $billMonth.'<br>';
$billMonthDays = cal_days_in_month(CAL_GREGORIAN, ($billMonth), date("Y"));
// echo $billMonthDays.'<br>';
if ($billMonthDays > $day) {
$billDay = $day;
} else {
$billDay = $billMonthDays;
}
}
I got this from here: http://www.midwesternmac.com/blogs/jeff-geerling/php-calculating-monthly
It returns the same date for the next month only, but how do I get the specific date of EACH month of the current year? Kindly leave your thoughts. Still a newbie here, sorry.
In that case, this should be enough:
<?php
for($i=8; $i<=12; $i++) {
echo sprintf('25-%02d-2015', $i) . '<br>';
}
but if you need more flexible way:
<?php
$date = new DateTime('25-08-2015');
function getCutoffDate($date) {
$days = cal_days_in_month(CAL_GREGORIAN, $date->format('n'), $date->format('Y'));
$date->add(new DateInterval('P' . $days .'D'));
return $date;
}
for($i = 0; $i < 5; $i++) {
$date = getCutoffDate($date);
echo $date->format('d-m-Y') . '<br>';
}
This should print:
25-09-2015
25-10-2015
25-11-2015
25-12-2015
25-01-2016

PHP add 1 month to date

I've a function that returns url of 1 month before.
I'd like to display current selected month, but I cannot use simple current month, cause when user clicks link to 1 month back selected month will change and will not be current.
So, function returns August 2012
How do I make little php script that adds 1 month to that?
so far I've:
<?php echo strip_tags(tribe_get_previous_month_text()); ?>
simple method:
$next_month = strtotime('august 2012 next month');
better method:
$d = new Date('August 2012');
$next_month = $d->add(new DateInterval('P1M'));
relevant docs: strtotime date dateinterval
there are 3 options/answers
$givendate is the given date (ex. 2016-01-20)
option 1:
$date1 = date('Y-m-d', strtotime($givendate. ' + 1 month'));
option 2:
$date2 = date('Y-m-d', strtotime($givendate. ' + 30 days'));
option 3:
$number = cal_days_in_month(CAL_GREGORIAN, date('m', strtotime($givendate)), date('Y', strtotime($givendate)));
$date3 = date('Y-m-d', strtotime($date2. ' + '.$number.' days'));
You can with the DateTime class and the DateTime::add() method:
Documentation
You can simple use the strtotime function on whatever input you have to arrive at April 2012 then apply the date and strtotime with an increment period of '+1 month'.
$x = strtotime($t);
$n = date("M Y",strtotime("+1 month",$x));
echo $n;
Here are the relevant sections from the PHP Handbook:
http://www.php.net/manual/en/function.date.php
https://secure.php.net/manual/en/function.strtotime.php
This solution solves the additional issue of incrementing any amount of time to a time value.
Hi In Addition to their answer. I think if you just want to get the next month based on the current date here's my solution.
$today = date("Y-m-01");
$sNextMonth = (int)date("m",strtotime($today." +1 months") );
Notice That i constantly define the day to 01 so that we're safe on getting the next month. if that is date("Y-m-d"); and the current day is 31 it will fail.
Hope this helps.
Date difference
$date1 = '2017-01-20';
$date2 = '2019-01-20';
$ts1 = strtotime($date1);
$ts2 = strtotime($date2);
$year1 = date('Y', $ts1);
$year2 = date('Y', $ts2);
$month1 = date('m', $ts1);
$month2 = date('m', $ts2);
echo $joining_months = (($year2 - $year1) * 12) + ($month2 - $month1);
Since we know that strtotime(+1 month) always adds 30 days it can be some troubles with dates ending with the day 31, 30 or 29 AND if you still want to stay within the last day of the next month.
So I wrote this over complicated script to solve that issue as well as adapting so that you can increase all type of formats like years, months, days, hours, minutes and seconds.
function seetime($datetime, $p = '+', $i, $m = 'M', $f = 'Y-m-d H:i:s')
{
/*
$datetime needs to be in format of YYYY-MM-DD HH:II:SS but hours, minutes and seconds are not required
$p can only be "+" to increse or "-" to decrese
$i is the amount you want to change
$m is the type you want to change
Allowed types:
Y = Year
M = Months
D = Days
W = Weeks
H = Hours
I = Minutes
S = Seconds
$f is the datetime format you want the result to be returned in
*/
$validator_y = substr($datetime,0,4);
$validator_m = substr($datetime,5,2);
$validator_d = substr($datetime,8,2);
if(checkdate($validator_m, $validator_d, $validator_y))
{
$datetime = date('Y-m-d H:i:s', strtotime($datetime));
#$p = either "+" to add or "-" to subtract
if($p == '+' || $p == '-')
{
if(is_int($i))
{
if($m == 'Y')
{
$year = date('Y', strtotime($datetime));
$rest = date('m-d H:i:s', strtotime($datetime));
if($p == '+')
{
$ret = $year + $i;
}
else
{
$ret = $year - $i;
}
$str = $ret.'-'.$rest;
return(date($f, strtotime($str)));
}
elseif($m == 'M')
{
$year = date('Y', strtotime($datetime));
$month = date('n', strtotime($datetime));
$rest = date('d H:i:s', strtotime($datetime));
$his = date('H:i:s', strtotime($datetime));
if($p == '+')
{
$ret = $month + $i;
$ret = sprintf("%02d",$ret);
}
else
{
$ret = $month - $i;
$ret = sprintf("%02d",$ret);
}
if($ret < 1)
{
$ret = $ret - $ret - $ret;
$years_back = floor(($ret + 12) / 12);
$monts_back = $ret % 12;
$year = $year - $years_back;
$month = 12 - $monts_back;
$month = sprintf("%02d",$month);
$new_date = $year.'-'.$month.'-'.$rest;
$ym = $year.'-'.$month;
$validator_y = substr($new_date,0,4);
$validator_m = substr($new_date,5,2);
$validator_d = substr($new_date,8,2);
if(checkdate($validator_m, $validator_d, $validator_y))
{
return (date($f, strtotime($new_date)));
}
else
{
$days = date('t',strtotime($ym));
$new_date = $ym.'-'.$days.' '.$his;
return (date($f, strtotime($new_date)));
}
}
if($ret > 12)
{
$years_forw = floor($ret / 12);
$monts_forw = $ret % 12;
$year = $year + $years_forw;
$month = sprintf("%02d",$monts_forw);
$new_date = $year.'-'.$month.'-'.$rest;
$ym = $year.'-'.$month;
$validator_y = substr($new_date,0,4);
$validator_m = substr($new_date,5,2);
$validator_d = substr($new_date,8,2);
if(checkdate($validator_m, $validator_d, $validator_y))
{
return (date($f, strtotime($new_date)));
}
else
{
$days = date('t',strtotime($ym));
$new_date = $ym.'-'.$days.' '.$his;
return (date($f, strtotime($new_date)));
}
}
else
{
$ym = $year.'-'.$month;
$new_date = $year.'-'.$ret.'-'.$rest;
$validator_y = substr($new_date,0,4);
$validator_m = substr($new_date,5,2);
$validator_d = substr($new_date,8,2);
if(checkdate($validator_m, $validator_d, $validator_y))
{
return (date($f, strtotime($new_date)));
}
else
{
$ym = $validator_y . '-'.$validator_m;
$days = date('t',strtotime($ym));
$new_date = $ym.'-'.$days.' '.$his;
return (date($f, strtotime($new_date)));
}
}
}
elseif($m == 'D')
{
return (date($f, strtotime($datetime.' '.$p.$i.' days')));
}
elseif($m == 'W')
{
return (date($f, strtotime($datetime.' '.$p.$i.' weeks')));
}
elseif($m == 'H')
{
return (date($f, strtotime($datetime.' '.$p.$i.' hours')));
}
elseif($m == 'I')
{
return (date($f, strtotime($datetime.' '.$p.$i.' minutes')));
}
elseif($m == 'S')
{
return (date($f, strtotime($datetime.' '.$p.$i.' seconds')));
}
else
{
return 'Fourth parameter can only be any of following: Valid Time Parameters Are: Y M D Q H I S';
}
}
else
{
return 'Third parameter can only be a number (whole number)';
}
}
else
{
return 'Second parameter can only be + to add or - to subtract';
}
}
else
{
return 'Date is not a valid date';
}
}

PHP to calculate latest 31 March

i want to calculate latest 31-Mar .... suppose date is 1-Jan-2012 i want result as 31-mar-2011 and if is 1-April-2011 then also i want result 31-mar-2011 and if its 1-mar-2011 it should come as 31-mar-2010.....hope i made my self clear ...(with php) ... i al calculating date with this for financial year ...
always between 31-mar-lastyear to 1-April-thisyear
... year should be taken automatically ...
i was trying like this
31-mar-date('y') and 31-mar-date('y')-1
but its not working as its taking current year every time.
Here is an example using the wonderful strtotime function of php.
<?php
$day = 1;
$month = 1;
$year = 2011;
$date = mktime(12, 0, 0, $month, $day, $year);
$targetMonth = 3;
$difference = $month - $targetMonth;
if($difference < 0) {
$difference += 12;
}
$sameDateInMarch = strtotime("- " . $difference . " months", $date);
echo "Entered date: " . date("d M Y", $date) . "<br />";
echo "Last 31 march: " . date("t M Y", $sameDateInMarch);
// the parameter 't' displays the last day of the month
?>
Something like this:
function getLast() {
$currentYear = date('Y');
// Check if it happened this year, AND it's not in the future.
$today = new DateTime();
if (checkdate(3, 31, $currentYear) && $today->getTimestamp() > mktime(0, 0, 0, 3, 31, $currentYear)) {
return $currentYear;
}
while (--$currentYear) {
if (checkdate(3, 31, $currentYear)) {
return $currentYear;
}
}
return false;
}
var_dump(getLast());
It should return the year or false.
if (date('m')>3) {
$year = date('Y').'-'.(date('Y')+1);
} else {
$year = (date('Y')-1).'-'.date('Y');
}
echo $year;
this is to get the current financial year for India

Categories