• ベストアンサー

時間差分の表示について(php)

phpで簡単に時間の入力画面と受取側の画面を作りました。 入力データは、開始time型終了time型休憩はtime型とし 22:00を基準に終了時間が22を超えていて8時間を超えていれば 深夜残業、22を超えずに8時間を超えていなければ残業として います。引き算の式とデータ受取はうまくいっているようなのですが 受取側の条件で22:00のように(00:00)形式にしたいのですが ご教授頂けませんでしょうか?また例えば終了が22:45で開始が9:30 のような分単位の引き算式なども教えて戴ける方いらっしゃればお願いしたいです。よろしくお願い致します。参考に受取側のファイルを添付させて頂きます。

質問者が選んだベストアンサー

  • ベストアンサー
  • dell_OK
  • ベストアンサー率13% (766/5721)
回答No.1

分計算したい場合は、すべて分にするのが基本だと思います。 前提 ・終了が00:00を過ぎないこと ・実行マシンの時刻が00:00:00頃に実行しないこと $start = '09:30'; //POST $end = '22:45'; //POST $rest = '01:00'; //POST $zero = '00:00'; $start_time = strtotime($start); $end_time = strtotime($end); $work_minutes = ($end_time - $start_time) / 60; echo "勤務時間 {$work_minutes}\n"; $rest_time = strtotime($rest); $zero_time = strtotime($zero); $rest_minutes = ($rest_time - $zero_time) / 60; echo "休憩時間 {$rest_minutes}\n"; $work_minutes -= $rest_minutes; echo "労働時間 {$work_minutes}\n"; $work_const = 8 * 60; $over_minutes = $work_minutes - $work_const; $midnight = '22:00'; $midnight_time = strtotime($midnight); if ($work_minutes > $work_const) { if ($end_time > $midnight_time) { $over_title = '深夜残業'; } else { $over_title = '残業時間'; } } else { $over_title = '残業なし'; } $over_hm = gmdate('H:i', $over_minutes * 60); echo "{$over_title} {$over_minutes} {$over_hm}\n";

その他の回答 (1)

  • dell_OK
  • ベストアンサー率13% (766/5721)
回答No.2

回答No.1です。 いろいろと確認してから回答した方がよかったのかも知れませんが、やりとりの手間を省きたくてごっそりソースを投稿してしまい、後悔してしまったので、補足しておきます。 開始と終了と休憩の「time型」がどのようなものなのかわからなかったので、書式「00:00」でPOSTされてくるものとしました。 strtotimeはある時点からの経過秒数を返してくれます。  $start_time = strtotime($start);  $end_time = strtotime($end); 終了から開始を差し引いた秒数を求めて、 それを60で割り分に換算しておきます。 ここでは勤務時間としました。  $work_minutes = ($end_time - $start_time) / 60; 休憩をそのまま差し引きできないため、 休憩から「00:00」を差し引いた秒を求めて、分に換算します。  $rest_time = strtotime($rest);  $zero_time = strtotime($zero);  $rest_minutes = ($rest_time - $zero_time) / 60; 勤務時間-休憩で労働時間を求めます。 別の呼称なのに同じ変数を使いまわすのはよくありませんが、適当な変数名を思いつかなかったので使いまわしました。  $work_minutes -= $rest_minutes; 労働時間が8時間をこえていれば残業の判定。 if ($work_minutes > $work_const) { 以下の行は if の内側の方がよかったかも。  $over_minutes = $work_minutes - $work_const;  $midnight_time = strtotime($midnight); 残業が深夜なのかどうかを判定します。  if ($end_time > $midnight_time) { 残業時間(分)に60をかけて秒にし、書式「00:00」にします。 gmdateの使い方が正しいかどうかはわかりませんが、いい感じにしてくれます。  $over_hm = gmdate('H:i', $over_minutes * 60); 前提について ・終了が00:00を過ぎないこと strtotimeで時分だけを引数にしています。 こうするとある年月日が付加されて処理されます。 例えば「09:00」は「2021-10-17 09:00:00」になったりします。 たぶん現在の年月日が付加されています。 もし終了が「01:00」だった場合、人間はこれを見て「翌日の1時だな」と思うかも知れませんが、「01:00」は「2021-10-17 01:00:00」と処理されたりします。 開始と終了の大小関係がくずれてしまうので簡単に差し引きできなくなるため、「00:00」を過ぎないこととしました。 ・実行マシンの時刻が00:00:00頃に実行しないこと strtotimeを時分だけで多用しているからです。 さっき「現在の年月日が付加されて」と書きました。 実行マシンの時刻が「00:00:00」頃に実行した場合を考えてみます。 開始のstrtotime時点でマシン日付時刻が「2021-10-17 23:59:59」だった。 引数は「09:00」で「2021-10-17 09:00:00」となる。 終了のstrtotime時点でマシン日付時刻が「2021-10-18 00:00:00」だった。 引数は「18:00」で「2021-10-18 18:00:00」となる。 これだと丸々1日加算されてしまいます。 なので日付が変わりそうなその瞬間に実行されないこととしました。 どちらの前提も、適当な日付を付加してstrtotimeを使えばなくせると思いますので、手を加えてみてください。

関連するQ&A

専門家に質問してみよう