为了账号安全,请及时绑定邮箱和手机立即绑定

获取日期间隔内的重复日期

获取日期间隔内的重复日期

PHP
森林海 2021-06-01 07:09:50
我想我被这个问题困住了,所以我希望你能给我一些如何解决这个任务的想法。我正在开发一个应用程序,它可以让您大致了解您的定期付款(我知道,这些东西已经存在,这只是一个副项目)和您的费用。API 快要完成了,但我在这部分挣扎:我需要知道在给定的时间跨度内是否需要定期付款。重复事件(合同)包含其他字段 startDate、endDate、intervalType(枚举 [每周、每月、每季度、每半年、每年])目前我有这个作为我的学说查询:return $this->createQueryBuilder('e')    ->andWhere('e.startDate >= :start')    ->andWhere('e.endDate <= :end')    ->andWhere('e.user = :user')    ->setParameter('start', $start)    ->setParameter('end', $end)    ->setParameter('user', $user)    ->getQuery()    ->getResult();其中参数 start 和 end 是间隔帧。但是我如何检查合同是否在选定框架内到期以及多久到期?Afaik 这只能通过迭代查询结果并检查合同是否与时间范围相交并注意在此期间发生的频率和时间来实现。但我不知道我怎么能做到这一点。示例数据:[name, intervalType, startDate, endDate, amount]rent, monthly, 2019-01-01, 2020-10-11, -500utility, monthly, 2019-01-01, 2020-10-11, -150salary, monthly, 2019-01-01, 2020-10-11, 1700investment, biannually, 2019-02-10, null , 2500food, weekly, 2019-01-01, null , -50如果我有这个月的时间表(2019-05-01 - 2019-05-31),我会得到这些合同:rent 2019-05-01utility  2019-05-01salary 2019-05-01food 2019-05-01food 2019-05-08food 2019-05-15food 2019-05-22food 2019-05-29如果我选择以下 2 个月(2019-07-01 - 2019-08-31),我会得到这个:rent 2019-07-01rent 2019-08-01utility  2019-07-01utility  2019-08-01salary 2019-07-01salary 2019-08-01food 2019-07-01food 2019-07-08food 2019-07-15food 2019-07-22food 2019-07-29food 2019-08-01food 2019-08-08food 2019-08-15food 2019-08-22food 2019-08-29investment 2019-08-01DateTime 和 DateInterval 可以实现吗?
查看完整描述

1 回答

?
慕村9548890

TA贡献1884条经验 获得超4个赞

每周间隔的逻辑在我看来是错误的。至少在我的银行应用程序中,每周计划总是在同一个工作日,两次连续发生之间有 7 天。


因此,根据该逻辑,您可以使用此功能:


function getScheduleBetween($data, $intervalStart, $intervalEnd) {

    $ref = [

        "yearly" => [12, "months"],

        "annually" => [12, "months"],

        "biannually" => [6, "months"],

        "quarterly" => [3, "months"],

        "monthly" => [1, "months"],

        "weekly" => [7, "days"],

        "daily" => [1, "days"]

    ];

    $intervalStart = new DateTime($intervalStart);

    $intervalEnd = new DateTime($intervalEnd);

    $result = [];

    foreach($data as $schedule) {

        // Convert start/end to DateTime

        $startDate = new DateTime($schedule["startDate"]);

        $endDate = $schedule["endDate"] ? min(new DateTime($schedule["endDate"]), $intervalEnd) : $intervalEnd;

        $name = $schedule["name"];

        $interval = $schedule["intervalType"];

        if (!isset($ref[$interval])) throw "Invalid interval type";

        list($coeff, $interval) = $ref[$interval];

        $match = clone $startDate;

        if ($match < $intervalStart) {

            $diff = $intervalStart->diff($match);

            $count = $interval == "days" ? $diff->format("%a") : $diff->m + $diff->y * 12 + ($diff->d ? 1 : 0);

            $count = ceil($count / $coeff) * $coeff;

            $match->modify("+$count $interval");

        }

        while ($match <= $endDate) {

            $temp = clone $match;

            $result[] = ["name" => $name, "date" => $temp->format("Y-m-d")];

            $match->modify("+$coeff $interval");

        }

    }

    array_multisort(array_column($result, "date"), $result);

    return $result;

}

使用示例:


$data = [

    ["name" => "rent", "intervalType" => "monthly", "startDate" => "2019-01-01", "endDate" => "2020-10-11", "amount" => -500],

    ["name" => "utility", "intervalType" => "monthly", "startDate" => "2019-01-01", "endDate" => "2020-10-11", "amount" => -150],

    ["name" => "salary", "intervalType" => "monthly", "startDate" => "2019-01-01", "endDate" => "2020-10-11", "amount" => 1700],

    ["name" => "investment", "intervalType" => "biannually", "startDate" => "2019-02-10", "endDate" => null, "amount" => 2500],

    ["name" => "food", "intervalType" => "weekly", "startDate" => "2019-01-01", "endDate" => null, "amount" => -50],

];


$result = getScheduleBetween($data, "2019-05-01", "2019-05-31");

print_r($result);

随着更大的时期:


$result = getScheduleBetween($data, "2019-05-01", "2019-08-31");

print_r($result);

如果您有其他类型的间隔,我相信您可以轻松扩展此功能以支持它们,即使使用“每周”的其他逻辑。


查看完整回答
反对 回复 2021-06-04
  • 1 回答
  • 0 关注
  • 118 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信