【问题标题】:Transform PHP script to a general-case function将 PHP 脚本转换为一般情况下的函数
【发布时间】:2017-07-24 17:51:09
【问题描述】:

我有这个代码可以按我想要的方式修改日期,例如,如果开始日期是 31/01/2000,添加 1 个月将返回 29/02/2000,然后,31/03/2000。 如果日期是 30/01/2000(不是该月的最后一天),它将返回 29/02/2000,然后是 30/03/2000、30/04/2000 等等。

我想在一般案例函数中转换该代码,以便能够添加 1、3、6、12 个月,并在 for 循环内,以正常工作。 我希望它是一个函数 2 或 3 个参数,startingDate,持续时间(迭代次数),频率(每次添加 1/3/6/12 个月)。

   <?php
$date = new DateTime('2000-01-28'); // or whatever
#echo $date->format('d')." ".$date->format('t');
$expectedDay = $date->format('d');
$month = $date->format('m');
$year = $date->format('Y');

for ($i = 0; $i < 100; $i++) {
    echo $date->format('Y-m-d')  . "<br>"; 
    if ($month++ == 12) {
        $year++;
        $month = 1;
    }

    $date->modify("${year}-${month}-1");
    if ($expectedDay > $date->format('t')) {
        $day = $date->format('t');
    } else {
        $day = $expectedDay;    
    }
    $date->modify("${year}-${month}-${day}");
}       

【问题讨论】:

    标签: php function


    【解决方案1】:

    Whelp,现在 PHP 中有一个非常简单的函数。

    首先,您将获得时间戳而不是日期时间:

    $timestamp = $date-&gt;getTimestamp();

    现在,只需使用strtotime 添加日期即可。

    strtotime("+1 month", $myTimestamp);

    您可以将 +1 更改为您想要的任何值,因此您只需将金额放入字符串中,瞧;添加它们的动态方式!

    然而,由于您想要 +30 天而不是自然月,您最好在时间戳上添加 30 天,如下所示:

    $timestamp = $timestamp + (3600 * 24 * 30); //s per h * h per d * d

    所以,你最终会得到这样的结果:

    function calculateTime($startingDate, $iterations, $frequency){
        $timeStamp = strtotime($startingDate);//if you expect a string date
        $timeToAdd = (3600 * 24 * 30) * $frequency; //30 days * frequency
        $return = array();
        $return[] = date('Y-m-d', $timeStamp); //Original date
        $previousDate = $timeStamp; //Original date  for now
        for($i = 0; $i < $iterations; $i++){
            $newDate = $previousDate + (3600 * 24 * 30);
            $return[] = date('Y-m-d', $newDate);
            $previousDate = $newDate;
        }
        return $return;
    }
    

    然后是渲染部分:

    //Let's render this stuff
    $dates = calculateTime('24-08-2017', 25, 3);
    foreach($dates as $date){
        echo "$date</br>";
    }
    

    如果你想用整月来做,像这样:

    <?php
    function calculateTime($startingDate, $iterations, $frequency){
        $timeStamp = strtotime($startingDate);//if you expect a string date
        $return = array();
        $return[] = date('Y-m-d', $timeStamp); //Original date
        $previousDate = $timeStamp; //Original date  for now
        for($i = 0; $i < $iterations; $i++){
            $lastDay = false;
            //It's the last day of the month
            if(date('t', $timeStamp) == date('d', $timeStamp)){
                $lastDay = true;
            }        
            if($frequency == 12){
                $newDate = strtotime('+1 year', $previousDate);  
            }
            else{
                if($lastDay){
                    $firstDayOfMonth = strtotime(date("01-m-Y", $previousDate));
                    $newDate =strtotime("+$frequency month", $firstDayOfMonth);
                }
                else{
                    $newDate = strtotime("+$frequency month", $previousDate);
                }
            }
            if($lastDay){
                $return[] = date('Y-m-t', $newDate);
            }
            else{
                $return[] = date('Y-m-d', $newDate);
            }
            $previousDate = $newDate;
        }
        return $return;
    }
    //Let's render this stuff
    $dates = calculateTime('31-01-2000', 25, 1);
    foreach($dates as $date){
        echo "$date</br>";
    }
    

    我希望这会有所帮助吗? :)

    如果您想快速了解它是如何工作的,只需将我的代码粘贴到phpfiddle。不幸的是,保存功能现在被破坏了。

    【讨论】:

    • 感谢您的帮助,但这不是我所期望的。当我介绍 2000 年 1 月 30 日的日期,频率 1 时,它给了我下一个日期 3 月 2 日。但是从我严格的限制来看,它必须给我 2000 年 2 月 29 日,然后是 30 月 30 日,4 月 30 日等等。如果开始日期是 1 月 31 日,则必须返回 2000 年 2 月 29 日、3 月 31 日、4 月 30 日、5 月 31 日...
    • @new_newB1e 嗯...获取一个月的最后一天也并不难(strtotime('last day of next month', $previousDate),但是您只需要在函数中添加一个差异来检查它是否是一个月的最后一天,然后抓住下个月的最后一天?
    • @new_newB1e 我已经更新了代码以包括本月的最后一天...很抱歉,除非有一个非常明确的节奏,否则我无法在这方面为您提供帮助您想添加这些月份。有特定的系统吗?如果它只是静态日期,您唯一的选择是执行 switch 案例或大量 if 语句。
    • 编辑的代码在很多情况下会错过二月如果我介绍 30/01/2000 或 31/01//2000,下一个日期将是 3 月 30/31 日:/
    • @new_newB1e 我为$lastDay 案例添加了一个例外。现在,如果是一个月的最后一天,它会先回到该月的第一天,然后添加一个月,然后它才会再次回到最后一天,然后再保存。现在它不再跳过二月了:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-23
    • 2021-08-15
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    相关资源
    最近更新 更多