所以我正在构建一个网站应用程序,用于计算任何用户拥有的账单到期金额。我设法让所有计算工作都很顺利,直到下个月到期。计算用户在账单到期之前获得多少薪水时,出了点问题。在几个var_dumps之后,我意识到当我将循环添加到循环中时,我想要额外的3600秒(在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比$ due_dates值高3600秒。我会假设因为夏令时。
那么我应该比较字符串值(日期('Y-m-d',$ due_date)== date('Y-m-d',$ next_payday))呢?当到期日与下一个发薪日相同时,这将起作用,但是当日期大于或小于时,它将不起作用。我注意到在将这些日期转换回字符串格式时,它们是相同的。或者有一种更好的方法可以做到这一点,我错过了。
在通过while循环的同时将3600添加到$ next_payday也可以,但我真的不想这样做。我敢肯定,当DST再次发生时,它会让我陷入困境,我会失去一个小时。
感谢您的任何意见。
答案 0 :(得分:1)
使用86400
或(60*60*24)
增加时间会在遇到DST事件时扭曲您的结果。幸运的是,当您添加天,周等时,strtotime()
不会受到影响
DateTime结构很好,但我还没有为任何简单的日期时间进程使用它。这种情况也不例外。
当我测试您的代码时,它从未进入while循环,因为strtotime()
值未被引用,因此被转换为设置$next_payday
大于$due_date
的意外时间戳。
此代码将正确计算日期范围内的付费期数:
//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;}