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

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

新規登録して質問してみよう
ただいま回答率
85.50%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

1回答

3384閲覧

PHPで時間計算する

Z-TALBO

総合スコア525

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

2クリップ

投稿2016/03/19 04:18

編集2016/03/19 07:02

現在タイムカードを作成しています。
一ヶ月分というか当月の○○さんで検索すると、その月のデータがずらっと出るようにしました。

PHP

1<form action="" post=""> 2<select name="year"> 3<select name="month"> 4<select name="name"> 5// 中は省略しています 6<input type="submit" name="serch" value="検索"> 7</form> 8 9// データの受取と少し細工 10$year = $_POST['year']; 11$month = $_POST['month']; 12$month = sprintf("%02d", $month); 13$name = $_POST['name']; 14$startday = $year . $month . '01'; 15$endday = date('Y-m-t', strtotime($year . '-' . $month)); 16 17// DBに接続し、SELECT 18省略 19 20// 抽出して表示 21while ($row = $stmt->fetch()) : 22$datetime = $row['period_dttm']; 23list ($year, $month, $day, $hour, $minutes, $second) = preg_split('/[-: ]/', $datetime); 24 25// 時刻の丸め処理 26$minutes = round($minutes / 5) * 5; 27$time = mktime($hour, $minutes, 0, 1, 1, 2000); 28$minutes = date('i', $time); 29$hour = date('H', $time); 30?> 31 32// table形式で表示させる予定なので、、、 33<tr> 34<td><?= h($row['name']); ?></td> 35<td><?= h($row['dakoku']); ?></td> 36<td><?= h($month) . '/' . h($day); ?></td> 37<td><?= h($hour) . ':' . h($minutes); ?></td> 38</tr> 39<?php endwhile; ?>

多少省略して書いてしまっておりますが、だいたいの流れとしてはこのような感じで作成してみました。
表示等に関しては特に問題はなく、検索も抽出も表示もできております。


ここからが、本題であります。
一ヶ月分の$hour . $minutesを計算したいのですが、、、いくつか条件がありまして、それを踏まえつつやるにはどのような方法があるのかと思い質問いたします。

1.$row['dakoku']
出勤、退勤、休入、休戻、待入、待戻のいずれかが入っております。

2.計算式としては
(退勤 - 出勤) - (休戻 - 休入) - (待戻 - 待入)=1日の実働時間
※ここで()をつけたのは、もしかしたらこうやってまず3つの分類で計算したものを最終的に計算するのがいいのかな?と思っただけです。。。。

3.例
検索の結果下記のように表示されたとします
職員名 打刻 月日 時分
○○ 出勤 3/19 9:00
○○ 休入 3/19 12:00
○○ 休戻 3/19 13:00
○○ 退勤 3/19 18:00
○○ 出勤 3/20 9:00
○○ 待入 3/20 10:30
○○ 待戻 3/20 11:00
○○ 休入 3/20 12:00
○○ 休戻 3/20 13:00
○○ 待入 3/20 15:00
○○ 待戻 3/20 16:00
○○ 退勤 3/20 18:00
※長くなってしまうので、これくらいにしておきます。
上記の場合
3/19 18:00-9:00-(13:00-12:00)=8:00
3/20 18:00-9:00-(11:00-10:30)-(13:00-12:00)-(16:00-15:00)=6:30
「3月の実働は14時間30分です。」

このような結果を、データを検索したついでに同時に出しておきたいのですが、どのような方法が考えられますか?

Excelなどでも作業のためだけの列を作ったりして、その作業列で計算とかあるので、こちらでもそういった見えないけど、裏で作業列があってそこでまずはの計算してって形をするとどうなのか?とか考えたのですが、実行するスキルが乏しいので、アドバイスお願いできますか?


[追記]
1日の実働部分の表示ができるようになりました。ありがとうございます!

次に、実際は実働8:00であるのですが、表示は28800という数字になっておりました。そこで、、、

PHP

1$jitsudo = date('H:i', $jitsudo); 2// このフォーマットだと、8:00のはずが9:00となり、一時間常に多くなった 3 4$jitsudo = date('H:i', strtotime("-1 hours", $jitsudo)); 5// もう一時間多いならで、一時間引くという感じにしてみまして、一応表示はされましたが、こんな感じですかね?

さて、、、最後なのですが、、、
今は1日ごとの実働が表示されるというのは満足ですが、その実働の合計が表示されるようにしたいのですが、、、

最後にこの部分に関してのロジックをアドバイスお願いできますでしょうか?

※この質問は少し内容がずれてきてしまうので、一度解決済みとさせていただき新規に質問をいたします。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

まず、前提として、nameで絞り込まれており、period_dttmで昇順に並んでいるとします。

PHP

1... 2// 抽出して表示 3$data = []; 4$jitsudo = 0; 5while ($row = $stmt->fetch()) : 6 $datetime = $row['period_dttm']; 7 list ($year, $month, $day, $hour, $minutes, $second) = preg_split('/[-: ]/', $datetime); 8 9 // 時刻の丸め処理 10 $minutes = round($minutes / 5) * 5; 11 $time = mktime($hour, $minutes, 0, 1, 1, 2000); 12 $minutes = date('i', $time); 13 $hour = date('H', $time); 14 if ($year != $data['year'] || $month != $data['month'] || $day != $data['day']) { 15 $jitsudo = ($data['退勤'] - $data['出勤']) - 16 (@$data['休戻'] - @$data['休入']) - 17 (@$data['待戻'] - @$data['待入']); 18 $data = []; 19 } 20 $data['year'] = $year; 21 $data['month'] = $month; 22 $data['day'] = $day; 23 $data[$row['dakoku']] = $time; 24 25 if($jitsudo): 26?> 27<tr> 28<td colspan="4">実働:<?= $jitsudo ?></td> 29</tr> 30<?php 31 $jitsudo = 0; 32 endif; 33?> 34// table形式で表示させる予定なので、、、 35<tr> 36<td><?= h($row['name']); ?></td> 37<td><?= h($row['dakoku']); ?></td> 38<td><?= h($month) . '/' . h($day); ?></td> 39<td><?= h($hour) . ':' . h($minutes); ?></td> 40</tr> 41<?php endwhile; 42 43$jitsudo = ($data['退勤'] - $data['出勤']) - 44 (@$data['休戻'] - @$data['休入']) - 45 (@$data['待戻'] - @$data['待入']); 46 47?> 48<tr> 49<td colspan="4">実働:<?= $jitsudo ?></td> 50</tr> 51```もしかしたら、出勤・退勤以外はない可能性も考慮して、その他はエラー抑制演算子を付けてます。 52日付が変わっているところで、実働時間の計算をしていますので、日付が渡った場合はちゃんと計算できません。 53なので、日付が渡る場合は、「$dataが空じゃなくてdakoku=出勤のデータが現れたら」とかにするといいかもしれませんね。

投稿2016/03/19 04:54

編集2016/03/19 06:20
shi_ue

総合スコア4437

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Z-TALBO

2016/03/19 06:02

いつも回答ありがとうございます! とりあえず、、、同じコードを入れてみましたが、、、エラー等は無かったのですが、変化が無く、、、 回答にありました絞込み等に関する部分について追記いたしますので、そこが原因か見ていただけますか?
shi_ue

2016/03/19 06:04 編集

ああ、ごめんなさい。&&と||を間違えてました。 よくやるんですよね・・・
Z-TALBO

2016/03/19 06:13

修正しました! 逆にそういうのも書いてみてあれ?って気づければ立派なんですが、、、 確かに、実働でました! ちょっとしたエラーといいますか、、、日付毎になってないのです。。 ○○ 3/19 出勤 ○○ 3/19 退勤 ○○ 3/20 出勤 実働 ○○ 3/20 休入 ○○ 3/20 休戻 ○○ 3/20 退勤 ○○ 3/21 出勤 実働 ○○ 3/22 退勤 このようになってしまっているのですが、、、どのようにしたらいいでしょうか? すみません。
shi_ue

2016/03/19 06:14

あ、そりゃそうですね。 実行しながら見れないからつらいです。いかに自分がロジックに弱いかが分かります。 ちょっとお待ちください修正します。
Z-TALBO

2016/03/19 06:16

お手数をおかけして申し訳ありません!
shi_ue

2016/03/19 06:17

直しました。
shi_ue

2016/03/19 06:22 編集

ああ、でも最後が狂うな・・・whileを抜けた後にも実働を出力する処理が必要です。 直しました。綺麗じゃないので、リファクタリングしてください。
Z-TALBO

2016/03/19 06:32

一応、最後も表示させることはできました! そして、、、最後なんですが、、、この場合とりあえず表示される値は28800とかの数字なんですが、 $jitsudo = date('H:i', $jitsudo);とかでやってみたら一応09:00とかで表示されるんですけど、一時間多いんですよ。 当たり前のことなのかもしれませんが、、、
Z-TALBO

2016/03/19 06:53

時間の部分に関して追記で記載してみました
Z-TALBO

2016/03/19 07:01

長くなるのと、少し中身の質問変更があるので、新規で質問出すことにしますね
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問