【问题标题】:How to determine a month has past to the date using Carbon如何使用 Carbon 确定一个月是否已经过去
【发布时间】:2019-10-03 23:29:57
【问题描述】:

一个人在每个月上平台后都会获得一个积分。因此,如果他在 7 月 3 日加入,他会在 8 月 3 日获得额外积分。

开始日期在数据库中设置为date 字段。

考虑到这一点,如果我只是在每日 cron 中做这样的事情,似乎有不同的情况我可能会错过添加这一点:

$startDate = new Carbon($startDateFromDb);
$today = new Carbon( date("Y-m-d"));

if ($startDate->day === $today->day) {
    //Add point!
}

例如,此人从 11 月 30 日开始。所以在 12 月 30 日,他应该得到 +1 分(现在总共有 1 分)。 1 月 30 日,他应该得到 +1 分(现在总共有 2 分)。

问题出现在 2 月,因为 2 月没有 30 天,所以 $startDate->day === $today->day 这个月永远不会成立。

如果一个人从 31 日开始,这也会发生在任何有 30 天的月份。

Carbon 是否有一些方法可以让我验证这一点,或者我应该用当前的月份/天数和我自己的逻辑来做一个很长的 if/else?

谢谢!

【问题讨论】:

  • 您的示例中的预期输出是什么?他在30天的时候拿到了当月的红利吗?
  • 是的!每月的天数无关紧要。他应该每个月,在他开始的那一天收到它。
  • 不检查相同的数字,检查是否是当月的最后一天。
  • @Nic3500 如果用户在15号开始,他应该在每个月的15号得到积分,而不是最后一天
  • 当用户在 11 月 30 日开始并且 2 月和 3 月出现时,预期的行为是什么?他们会在 2 月底(因为没有 2 月 30 日)和 3 月 30 日再次获得积分吗?

标签: php date php-carbon


【解决方案1】:

根据您正在寻找的确切行为以及您可以在数据库中存储的内容,有几个选项:

选项 1: 如果唯一可以调整一个人的分数的是任期,那么动态计算分数可能是最简单的。这可以很简单地使用 Carbon 的diffInMonths 来完成。这看起来像这样:

$startDate = new Carbon($startDateFromDb);
$today = Carbon::today();

$points = $today->diffInMonths($startDate);

选项 2: 如果您不能使用即时计算,那么最直接的方法是在总积分之外存储任期积分。这使您可以检查当前任期积分与授予的任期积分之间是否存在差异:

$startDate = new Carbon($startDateFromDb);
$today = Carbon::today();

$calcTenurePoints = $today->diffInMonths($startDate);
if ($calcTenurePoints < $awardedTenurePoints) {
    $points += $calcTenurePoints - $awardedTenurePoints;
    $awardedTenurePoints = calcTenurePoints
} 

您还可以通过仅存储非任期点并即时计算任期点来组合这两个选项。这样做的缺点是您不能轻松地直接从数据库中获取积分。

【讨论】:

    【解决方案2】:

    我终于手动完成了:

    public static function shouldAddVacationDay(User $user, Carbon $today) : bool {
    
        $shouldAddVacation = false;
    
        if ($user->startdate) {
    
            $start = new Carbon($user->startdate);
    
            // Normal day
            if ($today->day === $start->day) {
                $shouldAddVacation = true;
            }
    
            // Add a vacation day on March 1 for users that started Jan 29,30,31.
            if ($today->month === VacationlogController::$MAR && $today->day === 1) {
                if ($today->isLeapYear() && ($start->day === 30 || $start->day === 31)) {
                    $shouldAddVacation = true;
                } elseif ($start->day === 29 || $start->day === 30 || $start->day === 31) {
                    $shouldAddVacation = true;
                }
            }
    
            // If he started on the 31st of a month where the following month has less than 31 days, add a
            // vacation day the following month on the 1st.
            if ($start->day === 31) {
    
                if ($today->month === VacationlogController::$MAY && $today->day === 1) {
                    $shouldAddVacation = true;
                }
    
                if ($today->month === VacationlogController::$JUL && $today->day === 1) {
                    $shouldAddVacation = true;
                }
    
                if ($today->month === VacationlogController::$OCT && $today->day === 1) {
                    $shouldAddVacation = true;
                }
    
                if ($today->month === VacationlogController::$DEC && $today->day === 1) {
                    $shouldAddVacation = true;
                }
            }
        }
    
        return $shouldAddVacation;
    }
    

    【讨论】:

      猜你喜欢
      • 2012-07-07
      • 2022-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多