質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.53%

PHP 一ヶ月の実働時間の合計を出したい

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 2,608

Z-TALBO

score 491

タイムカードを作成しております。
現在、打刻する仕組みや、検索する仕組み、表示、修正、削除といった仕組みに関してはなんとか形になってきております。

最後に、集計といいますか、一ヶ月分の実働の合計を出す仕組みを探しております。

// 少し、回答者様からすると、無駄の多いコードになっているかもしれませんが、ご容赦ください。。。。

// 基本的に、年月と名前を選択して、検索します。
// 結果としては、○○年○○月の○○さんのデータという形になります。
// 並びは昇順です。

// DB接続 SELECT実行
省略いたします
$stmt->execute();

while ($row = $stmt->fetch()) :
$data = [];
$jitsudo = 0;
// datetimeを分解
$datetime = $row['period_dttm'];
list($year, $month, $day, $hour, $minutes, $second) = preg_split('/[-: ]/', $datetime);

// 丸め処理
$minutes = round($minutes / 5) * 5;
$time = mktime($hour, $minutes, 0, 1, 1, 2000);
$minutes = date('i', $time);
$hour = date('H', $time);

// 実働計算
if ($year != $data['year'] || $month != $data['month'] || $day = $data['day']) {
$jitsudo = ($data['退勤'] - $data['出勤']) - ($data['休戻'] - $data['休入']) - ($data['待戻'] - $data['待入']);
$data = [];
}
$data['year'] = $year;
$data['month'] = $month;
$data['day'] = $day;
$data[$row['dakoku']] = $time;

if ($jitsudo) :
// 実働を時間表示
$jitsudo = date('H:i', strtotime('-1 hours', $jitsudo));
?>

// table表示
<tr>
<td colspan="4">実働 :<?= $jitsudo; ?></td>
</tr>
<tr>
<td><?= h($row['name']); ?></td>
<td><?= h($row['dakoku']); ?></td>
<td><?= h($month) . '/' . h($day); ?></td>
<td><?= h($hour) . ':' . h($minutes); ?></td>
</tr>
<?php endwhile;
$jitsudo = ($data['退勤'] - $data['出勤']) - ($data['休戻'] - $data['休入']) - ($data['待戻'] - $data['待入']);
$jitsudo = date('H:i', strtotime('-1 hours', $jitsudo));
<tr>
<td colspan="4">実働 :<?= $jitsudo; ?></td>
</tr>

こちらで教えていただきながら、一応このように書きました。
表示に関しては特に問題もなく、「一日分の実働」がその日の終わりのとこに表示されます。


ここから質問となります。
1.「一日分の実働」の一ヶ月分の合計を出したい。
$jitsudoをなんとか足して足してでいきたいのですが、そのロジックがわかりません。

2.これは、難しければいいのですが、、、
待機の条件に
○待戻 - 待入 = 30分未満だったら、計算しない又は0
を追加できますか?
例えば
○○さんのデータで、
出勤 9:00
休入 12:00
休戻 13:00
退勤 18:00
=実働 8:00
出勤 9:00
待入 10:00
待戻 11:00
休入 12:00
休戻 13:00
退勤 18:00
=実働 7:00
出勤 9:00
待入 10:00
待戻 10:20→30分未満なので0とする
休入 12:00
休戻 13:00
退勤 18:00
=実働 8:00
出勤 9:00
待入 10:00
待戻 10:20→30分未満なので0とする
休入 12:00
休戻 13:00
待入 15:00
待戻 15:30→30分以上なので計算する
退勤 18:00
=実働 7:30
// 1.の質問内容
合計実働 = 30:30

難しい内容かもしれませんが、どうかアドバイスいただけますでしょうか?
よろしくお願い致します。


[追記]
本当に理解力が乏しく、、、いろいろやってみているのですが、結局うまくいかず、、、こちらに追記させてください。。。

$data = []; // $dataっていう配列の初期化
$jitsudo = 0; // $jitsudoの初期値?
if ($day = @data['day'] && $data) { // もしも、$dayがdata['day']と$dataだったら
$jitsudo = 計算 // $jitsudoに計算式を入れる。
$data = []; // 配列の初期化
}

$data['year'] = $year;
$data['month'] = $month;
$data['day'] = $day;
$data[$row['dakoku']] = $time; // dakokuにmktimeした$timeを?

if ($jitsudo) : // もし$jitsudoがあったら
?>
<tr>
<td colspan="4">実働:<?= $jitsudo; ?></td> // 実働表示
</tr>
<?php
$jitsudo = 0;
endif;
?>
<tr>
<td><?= h($row['name']); ?></td> // 名前表示
<td><?= h($row['dakoku']); ?></td> // 打刻の種別
<td><?= h($month) . '/' . h($day); ?></td> // 月/日
<td><?= h($hour) . ':' . h($minutes); ?></td> // 時:分
</tr>
<?php
endwhile;
$jitsudo = 計算
?>
<tr>
<td colspan="4">実働:<?= $jitsudo; ?></td> // 実働表示
</tr>
<?php
$jitsudo = 0;
endif;
?>


流れとして
while内に計算と表示があって、while抜けてから最後の計算って流れなんですが、
while内では無いようにしたりとかしたり、してみたのですが、、、
どうなっているのか、よくわからなくなってしまい、、、、
手が詰まりました。。。。

待機のことなどは、特にあれば良いななので、ここでは実働の表示だけで大丈夫です。

レベルが低く申し訳ありません。。。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

+3

直接の回答じゃないけど、

  • データをそろえる処理
  • そろったデータを表示する

の2つに、明確に処理を分けたほうがよいですね。
前半は全部のデータを作っておくって感じ。

データ作りながらHTML表示、とかやってると、本当に混乱しますし、余計な不具合を誘発することにもなります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/03/22 15:42 編集

    そういうのは自分で探すものなのでカジュアルに聞くと怒られちゃうYO!!!
    (それに質問は1タイトルで1つにしておくべき)

    一般的に技術者ってのは、自分でできることが無くなったら、そこで初めて人に聞く、という感じで覚えてきた人が多いので、開発力だけではなく、解決力も絶対に必要。

    『失敗怖がって最初から成功しようとしてる!』『いいとこ取りしてる!』って思われてしまうと、そのうち相手にされなくなるので、まずは手を動かそう。

    考えるよりそのほうが早いっす。
    答えは検索結果にもあるし、書店にもあるよ。もちろんAmazonにもあるだろうね。

    キャンセル

  • 2016/03/22 15:44

    そうですね。。。いろいろ見てみようと思います。

    ちょっと質問の内容からだいぶそれてしまい申し訳ありませんでした。

    キャンセル

  • 2016/03/22 15:44

    > 開発力だけではなく、解決力も絶対に必要。

    に同意します。

    キャンセル

checkベストアンサー

+1

条件が間違ってました。日が変わったとき&$dataが入っているとき実働時間を計算します。

if ($year != $data['year'] || $month != $data['month'] || $day = $data['day']) {
↓
if ($day != @$data['day'] && $data) {

実働時間を表示するときに

function sec_to_time($sec) {
  return 
    floor($sec / 3600).":".
    sprintf('%02d',floor(($sec / 60) % 60));
}

のような関数を作って自分で時間を表示しましょう。date関数はUTCからなので、日本では9時間ずれます。(9時間多くなる)

また、30分ごとにするところですが、5分単位で丸めているんですから、そこを変えればいいのでは?
そのあたりは、ご自分で考えてみてください。

四捨五入はroundですが、切り捨てはfloorです。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/03/19 17:41

    試した結果を追記で書きます

    キャンセル

  • 2016/03/19 17:43 編集

    はたと見たら、いろいろ間違えてました。修正しました。
    typoでした。

    コピペだけでは、だめですよ!自分で仕組みを考えてくださいね。

    キャンセル

  • 2016/03/19 18:18

    ちょっと、自分でいじってまたコメントいたします。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.53%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る