打刻

勤怠管理システムの自作-打刻時刻の丸め

当システムでも打刻時刻の丸め機能を搭載しました。

丸め種別説明
なし打刻された時刻をそのまま保持します。
切り上げ時刻を後ろにずらすように丸めます。
8:55 → 9:00
切り下げ時刻を前にずらすように丸めます。
18:03 → 18:00
丸め四捨五入のような形で直近の基準時刻に合わせます。
8:55 → 9:00
9:04 → 9:00
「こんなこともできる」というだけの機能で、実際には使われない想定です。

丸め間隔の選択肢は0分、5分、10分、15分です。
30分という選択肢がありませんが、個人的に「これ以上切り詰められるのは嫌」という意地で選択肢を用意しませんでした。
実装上は30分単位の丸めにも対応しています。

法的な扱い

打刻時刻の切り上げ・切り捨て機能自体は搭載しても問題ありませんが、実働時間が減る運用は違法になるようです。
例外として、月単位での合計値については部分的に丸め処理が認められています。

奇策として、常に労働者が有利になるように丸め処理をするのは違法ではなさそうです。
・始業時刻を切り下げ 9:03 → 9:00
・終業時刻を切り上げ 17:57 → 18:00

参考資料
・労働基準法 第24条 “その全額を支払わなければならない”
・昭和63年3月14日 基発150号

昭和63年3月14日 基発150号について
事務簡便のために下記の処理が認められています。
いずれも、1か月間の合計(月報の集計欄に出る値)の事を指しています。
・時間外労働の合計値を30分単位で切り上げ・切り捨て
・休日労働の合計値を30分単位で切り上げ・切り捨て
・深夜労働の合計値を30分単位で切り上げ・切り捨て
その他、賃金の額についても切り上げ・切り捨ての記述がありますが、そちらは給与計算システム側で何とかするはずなので無視します。

昭和63年3月14日 基発150号の原文が厚生労働省から出ていそうな気がしますが、見つかりませんでした。
私が調べた限りでは下記サイトでPDFファイルが閲覧できました。
http://www.joshrc.org/
↑サイト内にある検索欄に”150号”と入力して検索する
https://jaidunion.wordpress.com/link/
↑ページ内検索で”150”と検索する

当システムとしては、基発150号にある切り上げ・切り捨てを実現する処理は搭載していません。
そろばんで計算していた時代の「事務簡便」という理由は、現代では通用しないだろうと考えて実装の優先度を下げた結果、実装を忘れてしまいました。

当システムでは、丸め処理結果とは別に、打刻された時点の正確な日時を保持しています。
さらに各ユーザーが自分の打刻データをCSVファイルとしてダウンロードする機能も付いています。
丸め機能が不適切な形で利用された場合、CSVファイルを見れば切り詰められた実働時間をある程度推測することができます。

運用時の注意

打刻機能の利便性を保ったまま、法律に従って運用するためには、下記のようなルールを用意するのが落としどころになると思います。

  • 打刻の丸め、特に終業時の打刻で切り捨てが行われることを従業員に周知する
  • 切り捨て対象となる時間帯に勝手に働かないこと
  • 業務に関係する物品の片付けや着替えは、業務時間内に終わらせること
  • 打刻を終えた者を呼び止めることを禁止する

実装エピソード

元々打刻の丸め処理を実装する気はありませんでした。
労働時間はシステム側で計算するため、計算を楽にするという意味での丸め処理は必要なく、5分程度の残業も厳密に記録するべきだと考えていました。

丸め処理を実装しない前提でDB設計をしたため、後述の問題を抱えることになりました。

丸め機能の実装に至った経緯
打刻機能の実装を終えて個人的に運用してみた結果、とても不便で、丸め機能を搭載しなければうまく運用できないと感じました。
●本当に働いていない時間も実働時間に含まれてしまう
・早めにオフィスに到着しても始業直前まで打刻不可
・終業後、打刻端末の前で雑談するだけで給料が数円増える
●会社の管理体制
・今まで10分/15分区切りで運用しており、突然運用を変えるのは負担が大きい

データ構造

打刻データを保持するテーブルのPKは、「ユーザーID」と「打刻時刻」にしました。
このテーブル構造で丸め処理を搭載した場合、PKの重複エラーが起きてしまいます。
既に大部分の実装が完了してからこの問題に直面したため、DB構造の変更以外で対処することにしました。

当システムでは丸め処理の結果とは別に、打刻された時点の正確な日時を保持していますが、データ重複問題への対策としても使っています。

データ重複問題

丸め処理の結果、不正な値が登録されてしまう場合があります。
例えば15分単位で丸める設定をしていた場合・・・

①データ重複
出勤して打刻した。 8:50→9:00
始業直後に体調が悪化し早退した。9:05→9:00
出勤時刻 9:00 退勤時刻 9:00
実働時間が0になってしまいますが、労働していた時間をシステム側が勝手に無視するわけにはいかず、出勤日数としてもカウントする必要があります。
当システムの場合はPK重複で落ちます。

②時刻の逆転
出勤して打刻した。 8:50→9:00
直後に体温計測で異常値が出たため帰ることにした。8:51→8:45
出勤時刻 9:00 退勤時刻 8:45
このままの状態で月報を作った場合、実態とはかけ離れた実働時間になってしまいます。

データ重複問題への対策

丸め処理をした結果、異常なデータが作られてしまう場合、丸め処理を行わずにDBに登録します。
システムとしては正確な打刻時刻を残すことを優先して、判断は人間に任せます。

①丸め処理の結果、同じ日時、同じ打刻種別のデータと重複した場合
 登録は行わず、正常終了に見せかける。

②丸め処理の結果、同じ日時、別の打刻種別のデータと重複した場合
 切り上げの場合
  今回打刻されたデータは丸め処理をしない。重複した既存データの丸め処理も解除する。
 切り下げの場合
  今回打刻されたデータは丸め処理をしない。

④丸め処理の結果、別の打刻より前になってしまう場合(切り下げの場合のみ)
 今回打刻されたデータは丸め処理をしない。
 丸め処理をしない時刻のままでも、別の打刻と重複、または、別の打刻より前になってしまう場合
  重複した既存データの丸め処理も解除する。

実装での工夫

丸め処理の設定は、契約データごとに別々で持たせています。
通常勤務の従業員は丸め処理を実施、フレックスタイム制で在宅勤務する従業員は丸め処理を行わないといった設定が可能です。

さらに、契約データごとに専用の丸め処理ロジックを紐付けることができます。
これば導入する企業ごとに挙動をカスタマイズすることを前提とした機能です。
DB設定だけではカバーできないような複雑な条件がある場合、新たなロジックを実装して対応することもできます。

タイトルとURLをコピーしました