2017-02-28 22 views
0

私は、ユーザが持っている請求書の請求額を計算するウェブサイトアプリを構築しています。来月に請求書が来るまで、私はすべての計算をすばやく進めることができました。請求書が期限切れになる前にユーザーが何枚目の給料を支払ったかの計算に何か問題がありました。いくつかのvar_dumpsの後、私はループに日を追加するときに、余分な3600秒(3月12日の夏時間の間に得られた1時間)を思い付いていることに気付きました。したがって、すべてを計算するコードにピークがあります。これを見ている人々のために、これ以降数か月後に道路が掲示されます。今日の現在の日付は2017-02-27夏時間付きPHP DateTime

//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が要因であるとき以外の他の時間動作します)私は、ユーザーが前に持っているどのように多くの給料を決定しようとしていますが法案が期限です。問題は、このインスタンスが2の代わりに1を返すことです。なぜなら、$ next_paydayはループの2番目の反復が行われたときに実際に余分な3600秒が追加されるからです。これにより、$ due_datesの値よりも$ next_paydayが3600秒高くなります。私はDSTのために仮定します。

代わりに文字列の値(日付( 'Y-m-d'、$ due_date)==日付( 'Y-m-d'、$ next_payday))を比較する必要がありますか?これは、期日が次の給料日と同じ場合には機能しますが、日付が大/小である場合は機能しません。私はそれらの日付を文字列形式に変換するときに気付いた、彼らは同じです。それとも私が行方不明になっているより良い方法がありますか?

whileループを経由する間に3600を$ next_paydayに追加することもできますが、実際にはそうしたくありません。私は、DSTが再び起こる秋に私を台無しにするだろうと確信しています。

ありがとうございます。

+0

なぜstrtotime()とDateTimeを混在させるのですか? –

+0

最初は86400秒を追加していたからです。その部分はコメントアウトされました – kevin3954

答えて

1

86400または(60*60*24)を使用して時間を増加すると、DSTイベントが発生するたびに結果が歪みます。幸いにもstrtotime()は、日、週などを追加したときの影響を受けません。

DateTime構造体はすべて問題なく機能しますが、単純なdatetimeプロセスではまだ必要ありません。この場合も例外ではありません。

コードをテストしたところ、strtotime()の値は引用されていなかったので、を$due_dateより大きい値に設定した予期しないタイムスタンプに変換されたため、whileループに入りませんでした。

//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.:

このコードは、正しく日付範囲内payperiodの数を集計しますはい、whileループは読みにくいone-liner(常に私が探しているのが好きです)になっていた可能性があります。

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

ありがとうございました!誰かが私を理解してくれたのかしらと思っていた – kevin3954