Calculate a due date in PHP - php

One of my co-workers recently installed an open-source script into our billing system. The purpose is to re-calculate the next due date for a service when the customer's service is paid for late. Example being service is due 11/20/2012, is suspended the next day, and then they pay for it 11/25/2012. This script is supposed to update the next due date to 12/25/2012, but is malfunctioning and changing (monthly) dates that should be 12/25/2012 to 1/25/2013 for some reason.
I think the issue is with the way the $month variable is being handled, but can't quite figure out where the issue is.
function calculate_postpone_due_date($billingcycle)
{
switch($billingcycle)
{
case "Monthly": $months = 1; break;
case "Quarterly": $months = 3; break;
case "Semi-Annually": $months = 6; break;
case "Annually": $months = 12; break;
case "Biennially": $months = 24; break;
case "Triennially": $months = 32; break;
default: $months = 0; break;
}
//we return FALSE for any other billing cycles: "One Time", "Free Account" etc, they are not recurring
if ($months == 0)
return FALSE;
//a bit complex calculation based on day of the month
//exactly like native whmcs logic do
$year = date("Y");
$month = date("m");
$day = date("d");
for ($i=1; $i<=$months; $i++)
{
$month++;
if ($month == 13)
{
$month = 1;
$year++;
}
}
if (checkdate("$month", $day, $year))
{
return "$year-$month-$day";
}
else
{
//getting last day of the month
$last_day = date("t", mktime(0, 0, 0, $month, 1, $year));
return "$year-$month-$last_day";
}
}

function calculate_postpone_due_date($billingcycle)
{
switch($billingcycle)
{
case "Monthly": $months = 1; break;
case "Quarterly": $months = 3; break;
case "Semi-Annually": $months = 6; break;
case "Annually": $months = 12; break;
case "Biennially": $months = 24; break;
case "Triennially": $months = 36; break;
default: $months = 0; break;
}
if ($months == 0)
return FALSE;
$today = date('Y-m-d');
$next_due_date = strtotime($today.' + '.$months.' Months');
return date('Y-m-d', $next_due_date);
}

Try this (not tested):
function calculate_postpone_due_date($billingcycle)
{
switch($billingcycle)
{
case "Monthly": $months = 1; break;
case "Quarterly": $months = 3; break;
case "Semi-Annually": $months = 6; break;
case "Annually": $months = 12; break;
case "Biennially": $months = 24; break;
case "Triennially": $months = 32; break;
default: return FALSE;
}
$expires = new DateTime('plus '.$months.' months');
$expires->modify('last day of this month');
return $expires->format('Y-m-d');
}

function countDueDate($policy_start_date,$months){
$next_due_date = strtotime($policy_start_date.' + '.$months.' Months');
if($next_due_date<time()){
return countDueDate(date('Y-m-d', $next_due_date), $months);
}else{
return date('Y-m-d',$next_due_date);
}
}
function getModeMonth($premium_mode){
switch ($premium_mode){
case 'yearly': $q=12;break;
case 'monthly': $q=1;break;
case 'quarterly': $q=3;break;
case 'half year': $q=6;break;
default : $q=12;break;
}
return $q;
}
$date=countDueDate(date('Y').'-'.date('m-d',strtotime($policy_start_date)), getModeMonth($premium_mode));

Related

Get 3 future day dates with php

I want to creat a table for listing 3 future days with day name and date for my online shopping.
I try this code but it doesn't work correctly :
function week_from_monday($date) {
// Assuming $date is in format DD-MM-YYYY
list($day, $month, $year) = explode("-", $_REQUEST["date"]);
// Get the weekday of the given date
$wkday = date('l',mktime('0','0','0', $month, $day, $year));
switch($wkday) {
case 'Monday': $numDaysToMon = 0; break;
case 'Tuesday': $numDaysToMon = 1; break;
case 'Wednesday': $numDaysToMon = 2; break;
case 'Thursday': $numDaysToMon = 3; break;
case 'Friday': $numDaysToMon = 4; break;
case 'Saturday': $numDaysToMon = 5; break;
case 'Sunday': $numDaysToMon = 6; break;
}
// Timestamp of the monday for that week
$monday = mktime('0','0','0', $month, $day-$numDaysToMon, $year);
$seconds_in_a_day = 86400;
// Get date for 7 days from Monday (inclusive)
for($i=0; $i<7; $i++)
{
$dates[$i] = date('Y-m-d',$monday+($seconds_in_a_day*$i));
}
return $dates;
}
$ddate = date('Y-m-d');
$date = new DateTime($ddate);
$week = $date->format("W");
$week_number = $week;
$year = date('Y');
for($day=5; $day<=30; $day++)
{
echo date('m/d/Y', strtotime($year."W".$week_number.$day))."\n";
}
Here is my code but I want to get this :
today : Sun
Monday 30
Tuesday 31
Wednesday 1
To get the next 3 upcoming dates, you can simplify this a lot using date and strotime.
Try this code:
function nextThreeDays($date) {
$dateTs = strtotime($date);
// Dont need this, but I leave it for educational purpose:
// $day_of_week = date("N", $dateTs) - 1; // Mon=0 Tue=1 Wed=2 ...
// $monday_time = strtotime(date("d.m.Y H:i:s", $dateTs) . " -".$day_of_week." days"); // timestamp of monday of week of $date
for($i = 1; $i <= 3; $i++) {
echo date('m/d/Y', strtotime(date("d.m.Y H:i:s", $dateTs) . " +".$i." days"))."\n";
}
}
// Put in "today : Sun"
nextThreeDays("29.01.2023");
Outputs:
// Monday 30 Tuesday 31 Wednesday 1
01/30/2023
01/31/2023
02/01/2023

error get date time laravel

Hi
i bought a project from someone ,when i run it i have a problem .
the problem is when i try to load match with CURL from this link http://www.planetwin365.com/ControlsSkin/OddsEvent.aspx?ShowLinkFastBet=0&showDate=1&showGQ=1&rnd=049759534356372304&EventID=7944&GroupSep=undefined
to my database i show me this problem
this is my code
private function get_date_time($date,$time){
if(!Auth::user()->hasRole(['correction', 'admin'])){
return redirect('/');
}
//sabato 4 giugno 2016
$dates = explode(' ',$date);
$times = str_replace('.',':',$time);
switch ($dates[2]){
case 'gennaio':
$month = 01;
break;
case 'febbraio':
$month = 02;
break;
case 'marzo':
$month = 03;
break;
case 'aprile':
$month = 04;
break;
case 'maggio':
$month = 05;
break;
case 'giugno':
$month = 06;
break;
case 'luglio':
$month = 07;
break;
case 'agosto':
$month = 8;
break;
case 'settembre':
$month = 9;
break;
case 'ottobre':
$month = 10;
break;
case 'novembre':
$month = 11;
break;
case 'dicembre':
$month = 12;
break;
default:
$month = 01;
}
//2016-04-24 05:09:03
return $dates[3].'-'.$month.'-'.$dates[1].' '.$times;
}
please help me
Looks like $dates array has only three elements. Please remember the first index in an array is 0 not 1. I cannot confirm it as this service doesn't work in my country, but the following should do the trick.
switch ($dates[1]){
//...
$day = str_replace('.','',$dates[0]);
return $dates[2].'-'.$month.'-'.$day.' '.$times;

PHP DateInterval. Go back to the beginning of the year

I would like to write a method which I can give a period of time (Like: yearly, monthly...) and it returns me an anterior date according to this period of time given.
Here is my code:
public function callRuleCeilling($period)
{
$start = new \DateTime();
switch ($period) {
case 'weekly':
$dateInterval = 'P7D';
break;
case 'monthly':
$dateInterval = 'P1M';
break;
case 'quaterly':
$dateInterval = 'P3M';
break;
case 'half-yearly':
$dateInterval = 'P6M';
break;
case 'yearly':
$dateInterval = 'P1Y';
break;
default:
$dateInterval = 'P1Y';
}
$start->sub(new \DateInterval($dateInterval));
return $start
}
My example problem:
If I put a starting date in the middle of the year with a yearly period. I want it to stop at the beginning of the year.
And I would like the same for monthly period (Stop at the beginning of the month) etc...
Does it exist a PHP function with do that? I can't find it.
Please highlight me.
Thanks fo the highlight. It allowed me to did that way:
public function callRuleCeilling($period)
{
$start = new \DateTime();
$month = 'January';
switch ($period) {
case 'weekly':
$timestampMonday = strtotime('last monday', strtotime('tomorrow'));
$start = $start->setTimestamp($timestampMonday);
break;
case 'monthly':
$month = $start->format('F');
$start = new \DateTime('first day of '.$month);
break;
case 'quaterly':
$monthNumber = $start->format('n');
if($monthNumber >= 1) $month = 'January';
if($monthNumber >= 5) $month = 'May';
if($monthNumber >= 9) $month = 'September';
$start = new \DateTime('first day of '.$month);
break;
case 'half-yearly':
$monthNumber = $start->format('n');
if($monthNumber >= 1) $month = 'January';
if($monthNumber >= 7) $month = 'July';
$start = new \DateTime('first day of '.$month);
break;
case 'yearly':
$start = new \DateTime('first day of January');
break;
default:
$start = new \DateTime('first day of January');
}
return $start;
}

MySQL Where Date (not datetime) as Week of year

I have the following query using Symfony2, I want to convert i.fechaInicio which is date field Y-m-d (2013-08-31) to current week number so I can fetch results from current week...
$now = new \DateTime();
$semana = $now->format('W'); // Week Number
$query = $this->getEntityManager()
->createQuery("
SELECT i
FROM PgeIncidenciasBundle:Incidencia i
WHERE i.fechaInicio = :semana // This is wrong because compares
// Y-m-d with W so no results found...
")
->setParameters(array(
'semana' => $semana
))
;
try {
return $query->getResult();
}
catch (\Doctrine\ORM\NoResultException $e)
{
return null;
}
Use BETWEEN operator :
$from = new DateTime;
$from->setIsoDate($from->format('o'), $from->format('W'));
$to = clone $from;
$to->modify('+6 day');
$query = $this->getEntityManager()
->createQuery("
SELECT i
FROM PgeIncidenciasBundle:Incidencia i
WHERE i.fechaInicio BETWEEN :from AND :to
")
->setParameters(array(
'from' => $from->format('Y-m-d'),
'to' => $to->format('Y-m-d'),
));
Found a solution using WHERE IN() and generating an array of dates for current week.
public function findCounter()
{
$now = new \DateTime();
$semana = $now->format('Y-m-d');
$query = $this->getEntityManager()
->createQuery("
SELECT i
FROM PgeIncidenciasBundle:Incidencia i
WHERE i.fechaInicio IN (:semana)
")
->setParameters(array(
'semana' => $this->week_from_monday($semana)
))
;
try {
return $query->getResult();
}
catch (\Doctrine\ORM\NoResultException $e)
{
return null;
}
}
private function week_from_monday($date) {
list($year, $month, $day) = explode("-", $date);
$wkday = date('l',mktime('0','0','0', $month, $day, $year));
switch($wkday) {
case 'Monday': $numDaysToMon = 0; break;
case 'Tuesday': $numDaysToMon = 1; break;
case 'Wednesday': $numDaysToMon = 2; break;
case 'Thursday': $numDaysToMon = 3; break;
case 'Friday': $numDaysToMon = 4; break;
case 'Saturday': $numDaysToMon = 5; break;
case 'Sunday': $numDaysToMon = 6; break;
}
$monday = mktime('0','0','0', $month, $day-$numDaysToMon, $year);
$seconds_in_a_day = 86400;
for($i=0; $i<7; $i++)
{
$dates[$i] = date('Y-m-d',$monday+($seconds_in_a_day*$i));
}
return $dates;
}

strtotime instead of this very long function?

I am digging in the code this professional programmer had put together for an events website for me and I found this function that seems super confusing, as it looks like 1 line of code with "strtotime" would do the same thing.
Is it because we wanted to use "Jan 2nd" format with the two letters after the day of the month?
function convert_date_to_web($date) {
if (empty($date) || $date == "0000-00-00") return $date;
switch ($date[5].$date[6]) {
case '01':
$month = 'Jan';
break;
case '02':
$month = 'Feb';
break;
case '03':
$month = 'Mar';
break;
case '04':
$month = 'Apr';
break;
case '05':
$month = 'May';
break;
case '06':
$month = 'Jun';
break;
case '07':
$month = 'Jul';
break;
case '08':
$month = 'Aug';
break;
case '09':
$month = 'Sep';
break;
case '10':
$month = 'Oct';
break;
case '11':
$month = 'Nov';
break;
case '12':
$month = 'Dec';
}
if($date[9] == "1") {
$day = $date[9]."st";
}
else if ($date[9] == "2") {
$day = $date[9]."nd";
}
else if ($date[9] == "3") {
$day = $date[9]."rd";
}
else {
$day = $date[9]."th";
}
if($date[8] != "0") {
$day = $date[8].$day;
}
$date = $month." ".$day.", ".$date[0].$date[1].$date[2].$date[3];
return $date;
}
And my version is
$timestamp = strtotime($event->start_date);
$start_date = date("M d, Y", $timestamp);
Here is an exact replicate of the original function. I've used two versions, the first uses strtotime, the second uses explode to avoid using strtotime.
$date = '2011-10-01';
$date_format = 'M jS, Y'; // Three letter month, day name w/o leading zero, day suffix, year
echo date( $date_format, strtotime( $date)) . "\n";
$date_pieces = explode( '-', $date);
echo date( $date_format, mktime( 0, 0, 0, $date_pieces[1], $date_pieces[2], $date_pieces[0]));
Demo
Yup. I think that is what the reason for that long function is. It is to add in the "st", "nd", "rd", and the "th".
Your code does not do that. Maybe you can try it this way? (Needs debugging, cos i never tested it on actual php)
$timestamp = strtotime($event->start_date);
$start_date = date("M d", $timestamp);
$lastNum = substr($start_date, -1)
switch($lastNum) {
case "0":
break;
case "1":
$start_date .= "st"; break;
case "2":
$start_date .= "nd"; break;
case "3":
$start_date .= "rd"; break;
default:
$start_date .= "th"; break;
}
$start_date .= date(", Y", $timestamp);
The reason why I prefer such explode()ish solutions over strtotime(), too, is that they give deterministic, portable results that are less surprising while strtotime() does some complex magic.
As with all programming there is more than one way to do something. Experience teaches programmer to do things a certain way. From the look of this this function if for converting the default output format of mysql dates into a version that converts the month to a string. It looks good to me

Categories