1

我的一位同事最近在我们的计费系统中安装了一个开源脚本。目的是当客户的服务被延迟支付时,重新计算服务的下一个到期日。例如,服务于 2012 年 11 月 20 日到期,第二天暂停,然后他们在 2012 年 11 月 25 日付款。该脚本本应将下一个到期日期更新为 2012 年 12 月 25 日,但由于某种原因,该脚本出现故障并更改(每月)应为 2012 年 12 月 25 日至 2013 年 1 月 25 日的日期。

我认为问题在于处理 $month 变量的方式,但不能完全弄清楚问题出在哪里。

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

3 回答 3

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

}
于 2012-12-12T07:13:20.440 回答
1

试试这个(未测试):

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');
}
于 2012-12-12T06:58:24.163 回答
0
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));
于 2016-09-22T11:00:03.600 回答