PHP DateTime带有日光节省时间



因此,我正在构建一个网站应用程序,该应用程序计算任何用户拥有的账单的款项。我设法使所有计算都可以正常工作,直到下个月账单到期为止。在账单到期之前,用户获得多少薪水的计算出现了问题。经过几个var_dumps之后,我意识到,在循环中添加日子时,我会提出额外的3600秒(1小时在3月12日的日光节省时间获得的1小时)。因此,这是计算所有内容的代码的峰值。仅适用于在发布后几个月的路上看这件事的人们。今天的日期是2017-02-27

  //declare paychecks as counter
  $paychecks = 0;
  //the number of days a user has between paychecks
  $frequency = 14; 
  //users next payday
  $next_payday = strtotime(2017-03-10);
  //the date the next bill is due
  $due_date = strtotime(2017-03-24);

从理论上讲,在due_date之前应该有2个薪水。(第二付款会发生在账单到期的那一天)

  while ($next_payday <= $due_date) {
       $payday = new DateTime($next_payday);
       $date_array = $payday->add(new DateInterval('P'. $frequency . 'D'));
       $next_payday += strtotime($date_array->format('Y-m-d'));
       //I commented this out but this does not work either
       //$next_payday += ($frequency * 86400);
       //increase the counter
       $paychecks++;
   }

因此,从理论上讲(这是在DST是一个因素之外的任何其他时间),我试图确定用户在账单到期之前的薪水。问题在于,此实例返回1而不是2,因为$ next_payday实际上在循环的第二次迭代发生时实际上添加了3600秒。这使得$ next_payday 3600秒高于$ due_dates值。我认为是因为DST。

因此,我应该比较字符串值(date('y-m-d',$ due_date)== date('y-m-d',$ next_payday))吗?当截止日期与下一个发薪日相同时,这将起作用,但是当日期大于或小于以下时,这将行不通。我已经注意到,将这些日期转换回字符串格式时,它们是相同的。或者有更好的方法来做到这一点。

在经历WARE循环的过程中,将3600添加到$ next_payday,但我真的不想这样做。我敢肯定,当DST再次发生并且我损失了一个小时时,它会搞砸我。

感谢您的任何输入。

使用86400(60*60*24)增加时间时,每当遇到DST事件时,都会扭曲结果。幸运的是,当您添加几天,几周等时,strtotime()不会遭受影响。

DateTime构造都很好,但是我还不需要任何简单的DateTime流程。这种情况也不例外。

当我测试您的代码时,它从未输入WARE循环,因为strtotime()值未引用,因此将其转换为意外的时间戳,该时间戳设置了$next_payday大于$due_date

此代码将在日期范围内正确计算Payperiod的数量:

//declare paychecks as counter
$paychecks = 0;
//the number of days a user has between paychecks
$frequency = 14;
// or you could use 2 and set the strtotime unit to "+$frequency weeks"
//users next payday
$next_payday = strtotime("2017-03-10");  // this date value needed quotes
//the date the next bill is due
$due_date = strtotime("2017-03-24");  // this date value needed quotes
//echo date("Y-m-d",$next_payday),"<br>",date("Y-m-d",$due_date),"<br>";
while($next_payday<=$due_date){
    ++$paychecks;  // 2017-03-10 & 2017-03-24
    $next_payday=strtotime(date("Y-m-d",$next_payday)." +$frequency days");
}
//echo "next_payday=",date("Y-m-d",$next_payday),"<br>"; // this will be beyond $due_date
echo $paychecks;  // 2

P.S。是的,while循环本来可以变成不太可读的单线(我一直喜欢寻找)。

while($next_payday<=$due_date && $next_payday=strtotime(date("Y-m-d",$next_payday)." +$frequency days")){++$paychecks;}

最新更新