Как определить, что месяц прошел к дате, используя Carbon - PullRequest
0 голосов
/ 04 октября 2019

Человек получает очко после каждого месяца, проведенного на платформе. Поэтому, если он присоединится 3 июля, 3 августа он получит дополнительный балл.

Дата начала задается в БД в виде поля date.

Если подумать об этом, кажется,Существуют разные сценарии, в которых я могу пропустить добавление этого пункта, если я просто сделаю что-то подобное в ежедневном хроне:

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

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

Например, человек начинает 30 ноября. Таким образом, 30 декабря он должен получить +1 балл (теперь у него всего 1). 30 января он должен получить +1 балл (теперь их всего 2).

Проблема будет в феврале, так как в феврале нет 30 дней, поэтому $startDate->day === $today->day никогда не будет правдой в этом месяце.

Это также может произойти в любой месяц с 30 днями, если человек начинает с 31-го.

Есть ли у Carbon какой-либо метод, который позволил бы мне это проверить, или я должен просто сделать длинный, если/ еще с текущим месяцем / днями в месяце и моей собственной логикой?

Спасибо!

Ответы [ 2 ]

0 голосов
/ 06 ноября 2019

Я наконец сделал это вручную:

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;
}
0 голосов
/ 08 октября 2019

В зависимости от того, какое поведение вы ищете и что можете сохранить в своей базе данных, существует несколько вариантов:

Вариант 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
} 

Вы также можете объединить эти два варианта, только сохраняя баллы не владения и вычисляя баллы владения намуха. Недостатком такого способа является то, что вы не можете легко получить очки непосредственно из базы данных.

...