首页 > 解决方案 > 列出工资覆盖日期 PHP

问题描述

我想使用员工的最后工资日期生成工资覆盖日期列表。员工每 15 天领取一次薪水。因此,每个月的覆盖范围应该是当月的第 1 日 - 第 15 日和第 16 日 - 最后一天。

例如,

$last_salary_date = "2020-12-01";
$date_now = "2021-02-27";

// I should get the following start and end dates:
// 2020-12-01 - 2021-12-15
// 2020-12-16 - 2021-15-31
// 2021-01-01 - 2021-01-15
// 2021-01-16 - 2021-01-31
// 2021-02-01 - 2021-02-15
// 2021-02-16 - 2021-02-28

$last_salary_date = "2020-02-16";
$date_now = "2021-02-27";

// I should get the following start and end dates:
// 2021-02-16 - 2021-02-28

到目前为止,我已经做了这样的事情:

    $start_date = new DateTime("2021-01-16");
    $end_date = new DateTime(date("Y-m-d"));
    $interval = \DateInterval::createFromDateString('1 month');
    $period   = new \DatePeriod($start_date, $interval, $end_date);

    $salary_dates = [];
    foreach ($period as $dt) {
        if (date("Y-m-d") > $dt->format("Y-m-01")) {
            $salary_dates[] = (object) [
                'start_dt' => $dt->format("Y-m-01"),
                'end_dt' => $dt->format("Y-m-15")
            ];
        }
        
        if (date("Y-m-d") > $dt->format("Y-m-15")) {
            $salary_dates[] = (object) [
                'start_dt' => $dt->format("Y-m-16"),
                'end_dt' => $dt->format("Y-m-t")
            ];
        }
    }

    return $salary_dates;

问题是它仍然会在第一个月的 1-15 号开始,即使开始应该是 16 号。我正在考虑一个更好的方法来做到这一点。请帮忙

标签: php

解决方案


这是修改后的实现。它是为便于理解而绘制的,但也可以写成更短的形式。

<?php

$start_date = new DateTime("2021-02-16");
$end_date = new DateTime("2021-02-27");

$interval = \DateInterval::createFromDateString('1 month');
$period = new \DatePeriod($start_date, $interval, $end_date);

$salary_dates = [];
foreach ($period as $dt) {

    $check_date = function ($date) use ($start_date, $end_date) {
        // check if salary interval is in correct range
        return
            $start_date->format("Y-m-d") <= $date->start_dt
            and $end_date->format("Y-m-d") >= $date->start_dt; // are you sure it shouldn't be ->end_dt ? now it's on order
    };

    // check first two weeks in month
    $salary_date = (object)[
        'start_dt' => $dt->format("Y-m-01"),
        'end_dt' => $dt->format("Y-m-15"),
    ];

    if ($check_date($salary_date)) {
        $salary_dates[] = $salary_date;
    }

    // check second two weeks in month
    $salary_date = (object)[
        'start_dt' => $dt->format("Y-m-16"),
        'end_dt' => $dt->format("Y-m-t")
    ];

    if ($check_date($salary_date)) {
        $salary_dates[] = $salary_date;
    }
}

print_r($salary_dates);



推荐阅读