やりたいこと
文字列として扱われている時間をJavaScriptでいい感じに丸めたいです。
エレガントな書き方ができなかったのですが、ツッコミ待ちの気持ちで公開します。
背景
勤怠管理システム(Web画面)に入館・退館時刻が「HHMM」という形式の文字列で記録されています。
一方で、始業・就業時間は手入力なので、記録されている入退館時刻を丸めて自動でセットしたいと考えました。
- 始業時刻:入館時刻を切り上げていい感じの時間にする。(例 入館 08:52→ 始業 09:00)
- 就業時刻:退館時刻を切り捨てていい感じの時間にする。(例 退館 17:05→ 終業 17:00)
完成したコード
/**
画面から時刻を取得する対応は割愛。
取得した結果がarrivalTime/leavingTimeに格納されたものとする。
**/
const arrivalTime = 0852 //入館時刻
const leavingTime = 1705 //退館時刻
//時と分に分割する。
const arrivalHour = arrivalTime.substr(0,2);
const arrivalMin = arrivalTime.substr(2,2);
const leavingHour = leavingTime.substr(0,2);
const leavingMin = leavingTime.substr(2,2);
//入館時刻は切り上げして、退館時刻は切り捨てする。
//年月日は使わないので、適当な固定値をセットする。
const roundedArrTime = new Date(2018,0,1,arrivalHour,Math.ceil(arrivalMin/10)*10);
const truncationLvgTime = new Date(2018,0,1,leavingHour,Math.floor(leavingMin/10)*10);
//頭に0を付与して、4ケタになるよう調整する。
const strArrHour = ('0' + roundedArrTime.getHours()).slice(-2);
const strArrMin = ('0' + roundedArrTime.getMinutes()).slice(-2);
const strLvgHour = ('0' + truncationLvgTime.getHours()).slice(-2);
const strLvgMin = ('0' + truncationLvgTime.getMinutes()).slice(-2);
/**
画面にセットする対応も割愛
**/
コードの説明
/**
画面から時刻を取得する対応は割愛。
取得した結果がarrivalTime/leavingTimeに格納されたものとする。
**/
const arrivalTime = 0852 //入館時刻
const leavingTime = 1705 //退館時刻
//時と分に分割する。
const arrivalHour = arrivalTime.substr(0,2);
const arrivalMin = arrivalTime.substr(2,2);
const leavingHour = leavingTime.substr(0,2);
const leavingMin = leavingTime.substr(2,2);
//入館時刻は切り上げして、退館時刻は切り捨てする。
//年月日は使わないので、適当な固定値をセットする。
const roundedArrTime = new Date(2018,0,1,arrivalHour,Math.ceil(arrivalMin/10)*10);
const truncationLvgTime = new Date(2018,0,1,leavingHour,Math.floor(leavingMin/10)*10);
文字列を時刻として計算するために、時と分に分割して、Dateオブジェクトに格納します。
Dateオブジェクトに格納した理由は、時刻の計算をいい感じに調整してくれるためです。
補足: Date を複数の引数を伴ってコンストラクタとして呼び出された場所では、値が論理範囲より大きくても (month 値に 13 を与えたり、minute 値に 70 を与える)、調整された値になります。つまり、new Date(2013, 13, 1) は、new Date(2014, 1, 1) と等しくなるように調整され、両者とも 2014-02-01 の日付を生成します (month は 0 を起点とします)。同様に、他の値も次のようになります: new Date(2013, 2, 1, 0, 70) は new Date(2013, 2, 1, 1, 10) と等しくなり、2013-03-01T01:10:00 の日付を生成します。
「分」の一の位を切り上げ、切り捨てをしたいので、「分」を10倍してceilで切り上げしたのちに、10分の1倍して元に戻しています。
【JavaScript】数値を切り上げる - オープンリファレンス
//頭に0を付与して、4桁になるよう調整する。
const strArrHour = ('0' + roundedArrTime.getHours()).slice(-2);
const strArrMin = ('0' + roundedArrTime.getMinutes()).slice(-2);
const strLvgHour = ('0' + truncationLvgTime.getHours()).slice(-2);
const strLvgMin = ('0' + truncationLvgTime.getMinutes()).slice(-2);
/**
画面にセットする対応も割愛
**/
getHours/getMinutesで取得した時分をそのまま使えれば良いのですが、システムの都合上、0埋めの4桁で入力する必要があります。(例 9時5分→0905)
このため、時と分それぞれで頭に「0」を付与したうえで、sliceで末尾2桁を切り出します。
例)
9(時)→(頭に0を付与)→09→(末尾2桁を切り出す)→09
10(時)→(頭に0を付与)→010→(末尾2桁を切り出す)→10
課題
- もうちょっと美しい書き方がある気がする。
- 入退館時刻がHH時00分だった場合、始業・就業時刻も同じになってしまう。(切り上げ、切り捨てしても変わらないため)