dsf12313 2016-01-15 22:19
浏览 27
已采纳

PHP的DateTime数组似乎有些偏差

I am trying to create a function to create an array of DateTime(s). The dates I want are every Saturday in a given year.

I have a function that does this but when the values are stored in an array, they begin with the second Saturday of the year and extend to the first Saturday of the following year.

Note that the following displays a list of Saturdays as generated by the function and then after a couple of blank lines displays the Saturdays store in the array.

<?php
define ('sql','Y-m-d');
define ('br','<br/>');

function allSaturdays ($year){
    $endofyear = "$year-12-31";
    $interval = new DateInterval("P7D");

    $year--;
    $workingdate = "$year-12-31";  

    $workingdate  = strtotime ($workingdate);
    $workingdate  = strtotime ("next Saturday",$workingdate); 

    $workingdate  = date ("Y-m-d",$workingdate);   
    $workingdate  = new DateTime ($workingdate); 
    $result[] = new DateTime;
    while ($workingdate->format(sql) <= $endofyear ) {
       $result[] = $workingdate;
       echo $workingdate->format (sql).br;     
       $workingdate->add ($interval);
       $workingdate = new DateTime ($workingdate->format(sql));
       //echo $workingdate->format (sql)."#".br;;
    }// while
      unset ($workingdate);
      return $result;  

 }//function


  $sats = allSaturdays(2016);

  echo "<br/.<br/>";
  foreach ($sats as $saturday)
     echo $saturday->format(sql)."*<br>";


  ?>

However, if I store the only the date (2016-01-02) the correct values are in the array.

No doubt I'm missing something simple. Any help is appreciated.

Dave

  • 写回答

1条回答 默认 最新

  • douxueke5653 2016-01-15 22:23
    关注

    You are modifying your DateTime object after you placed it in the array.

    This is where you add it to the array:

    $result[] = $workingdate;
    

    And then the line after that adds 7 days to it:

    $workingdate->add($interval);
    

    Calling add modifies the original. If you want to make sure you're working on a copy, call clone first or use DateTimeImmutable instead of DateTime.

    Here's a new version of your code using DateTimeImmutable:

    function allSaturdays ($year){
    
        $endOfYear = new DateTimeImmutable("$year-12-31");
        $workingdate = new DateTimeImmutable("first saturday of January " . $year);
    
        while ($workingdate <= $endofyear ) {
           $result[] = $workingdate;
           $workingDate = $workingDate->modify('+7 days');
        }// while
        return $result;  
    
     }//function
    

    Here's another version that does not use DateTimeImmutable

    function allSaturdays ($year){
    
        $endOfYear = new DateTime("$year-12-31");
        $workingdate = new DateTime("first saturday of January " . $year);
    
        while ($workingdate <= $endofyear ) {
           $result[] = $workingdate;
           $workingDate = clone $workingDate;
           $workingDate->modify('+7 days');
        }// while
        return $result;  
    
     }//function
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 微信会员卡等级和折扣规则
  • ¥15 微信公众平台自制会员卡可以通过收款码收款码收款进行自动积分吗
  • ¥15 随身WiFi网络灯亮但是没有网络,如何解决?
  • ¥15 gdf格式的脑电数据如何处理matlab
  • ¥20 重新写的代码替换了之后运行hbuliderx就这样了
  • ¥100 监控抖音用户作品更新可以微信公众号提醒
  • ¥15 UE5 如何可以不渲染HDRIBackdrop背景
  • ¥70 2048小游戏毕设项目
  • ¥20 mysql架构,按照姓名分表
  • ¥15 MATLAB实现区间[a,b]上的Gauss-Legendre积分