【问题标题】:Monthly Commission Calculation PHP每月佣金计算 PHP
【发布时间】:2015-09-28 21:54:29
【问题描述】:

我遇到了一个带有 PHP 日期的编码器块。让我先描绘一下我想要发生的事情。例如:

$user_join_date = new DateTime('2015-01-31');
$today_date = new DateTime('2015-04-30');

每天都会运行一个 cron,对于本例,系统将在每 31 日(或 30-28 日,具体取决于月份)根据上个月的订单和数量为该用户计算佣金BETWEEN '2015-03-31' AND '2015-04-29'

所以我需要的是两个方面。首先,我需要确保我在正确的日期计算佣金,即:他们加入日期的每月周年纪念日或同月的等值日期。其次,我需要找到计算佣金的时间范围,如上面的 mysql 代码段所示。

出于显而易见的原因,我不能只说:

if ($user_join_date->format('d') == $today_date->format('d')){
    calc_commission();
}

因为这不会每个月都运行。如果我有任何不清楚的地方,请告诉我。

【问题讨论】:

  • 好的,但实际的问题是什么?
  • 顺便说一下,一个月的最后一天是另一个月的第一天的前一天。

标签: php mysql date datetime


【解决方案1】:

我认为您是在说您希望在每个用户注册日期后的整数个月内记入该帐户。你会发现 MySQL 的日期算法的一个方面非常方便——INTERVAL n MONTH 加法。

   DATE('2015-01-30') + INTERVAL 1 MONTH    ==>  '2016-02-28'
   DATE('2016-01-30') + INTERVAL 1 MONTH    ==>  '2016-02-29'

此功能很好地解决了工作日期间所有奇怪的公历问题。我将把日期称为续订日期。

现在,假设signup 列包含用户注册时的日期/时间戳。此表达式确定最近的每月续订日期。特别是,如果它等于 CURDATE(),则今天是续订日期。

 DATE(signup) + INTERVAL TIMESTAMPDIFF(MONTH, DATE(signup), CURDATE()) MONTH

下一个:这个密切相关的(呃!)表达式等于上个月的续订日期。

 DATE(signup) + INTERVAL TIMESTAMPDIFF(MONTH, DATE(signup), CURDATE())-1 MONTH

您可以只使用CURDATE() - INTERVAL 1 MONTH,但这在公历月末猴子业务方面更为准确。试试看:即使在 2016 年 2 月末(闰年)也能正常工作。

现在,您需要在计算中使用从上一个续订日期 >= 开始到当前续订日期 < 前一天结束的交易。在 MySQL 中按该日期范围过滤看起来像这样。

WHERE transdate >= DATE(signup) + 
                     INTERVAL TIMESTAMPDIFF(MONTH, DATE(signup), CURDATE())-1 MONTH
  AND transdate <  DATE(signup) + 
                     INTERVAL TIMESTAMPDIFF(MONTH, DATE(signup), CURDATE()) MONTH

【讨论】:

  • 对不起,我想我不够清楚。用户呼吁客户购买产品并使用他们的用户#作为促销代码/推荐号码。这导致用户在加入周年纪念日开始时获得佣金。即:用户于 31 日加入,因此他们上个月的佣金将根据月份在 31 日、30 日、29 日等计算。所以我试图确定两件事 1) 佣金应该在今天计算吗? 2) 根据周年纪念加入日期,用户上个月的日期范围是多少?
  • 确实是猴子生意。我只是假设我必须在 php 中执行此操作,但这要容易得多。非常感谢!
【解决方案2】:

$base_dt 是您的加入日期。因此,如果您将其传递给 checkIt 函数,它将根据今天是否为计费日为您提供真或假。

$base_dt        = new DateTime('2015-04-30', new DateTimeZone("America/Chicago"));

if(checkIt($base_dt)) {
    echo "true";
    //this is the day. 
} else {
    echo "false";
    //this is not the day.
}

所以check it函数应该是这样的.....

function checkIt($base_dt) {
    $base_d = $base_dt->format('j'); //without zeroes
    echo $base_d;
    $today        = new DateTime('now');
    $d = $today->format('j');
    echo $d;
    if($base_d == $d) {
        return true;
    } else if($base_d>28) {
        $base_dt->modify('last day of this month');
        $dif_base = $base_dt->format('j') - $base_d;    
        //echo $dif_base;

        $today->modify('last day of this month');
        $diff_today = $today->format('j') - $d;
        //echo $diff_today;

        if(($base_d==31 && $diff_today==0)||($base_d==30 && $diff_today==0 && $d<30)||($base_d==29 && $diff_today==0 && $d<29)) {
            return true;
        } 

        if($dif_base==0 && $diff_today==0) {
            return true;
        }
    }

    return false;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多