時間の範囲を検査する方法
先日、突如難題が入りました。
PHPにて23時から翌日8時ぐらいまで、
システムの一部を一時停止させたいという問題でした。
しかも毎日使えるように、入力される情報は、
開始時刻と終了時刻の「時」と「分」の4つの数値のみです。
本来は厳密には自分の担当ではなく、相談された事なのですが、
プログラムの流れとしてはほぼ同じようなものなので、
デバッグ機能を備えたGoogleAppsScriptのエディタを利用し、
JavaScriptで試してみました。
しかし、これが意外にも難しく、
その日の範囲ならば、単純にUNIX時間(1970年元日からの秒数)で計ればいいのですが、
日をまたいでいると、そうはいきません。
開始時刻と終了時刻に日付も含まれていれば簡単なのですが、
毎日使うため、そうもいきません。
何度か相談しつつも、なんとかこの問題を解決出来たのですが、
自分自身では解決には至らず、先を越されていました。
結論としては、開始時刻の「時」が終了時刻の「時」よりも大きい場合は、
翌日であると判断して処理を分け、開始時刻と終了時刻のUNIX時間を生成し範囲を作り、
現在のUNIX時間と比較するという結論になりました。
しかしその翌日に、自分のJavaScript版を完成させてみました。
//現時刻が時間の範囲に入っているかを見る関数。 // 引数1:開始時 引数2:開始分 引数3:終了時 引数4:終了分 //それぞれ数値で入力。 function timeRangeCheck(startTimeHours,startTimeMinutes,endTimeHours,endTimeMinutes){ //現在時刻が指定の範囲に入っていればtrueになる。 var timeRangeIn = false; var date = new Date(); var yy = date.getYear(); var mm = date.getMonth() + 1;//getMonth()での1月は0から始まるため、1加算。 var dd = date.getDate(); var nowUnixTime = Date.parse(date); var startUnixTime = Date.parse(yy+"/"+mm+"/"+dd+" "+startTimeHours+":"+startTimeMinutes+":0"); var endUnixTime = Date.parse(yy+"/"+mm+"/"+dd+" "+endTimeHours+":"+endTimeMinutes+":0"); //開始時刻が終了時刻を上回っていたら翌日と判断し、終了時刻に1日分のUNIX時間(GAS基準)を追加。 if((endTimeHours * 60) + endTimeMinutes < (startTimeHours * 60) + startTimeMinutes){ endUnixTime += 86400000; } //現時刻が開始時刻以上、終了時刻以下の範囲になるとtrueにする。 if(nowUnixTime >= startUnixTime && nowUnixTime <= endUnixTime){ timeRangeIn = true; } return timeRangeIn; }
GoogleApps用の関数はないため、
たぶん、通常のウェブページ用としても使えると思います。
ただ、途中で1日分の秒数を入力している箇所では、
GoogleAppsScript上で1日分のUNIX時間を計算したものなので、
もしかしたら、用途によってはケタ数に誤差が生じるかもしれません。
自分が独自に考えた方法では、開始時刻の「時」が終了時刻の「時」を
越えていた場合には翌日と判断するのは共通していますが、
ここで終了時刻のUNIX時間に、1日分の秒数を加算するという方法を取りました。
これで比較用のUNIX時間が作成できたので、
後は現時国のUNIX時間が、この範囲に入っているかを計算するだけです。
ただ、さらに問題を見つけました。
このままでは分単位で終了時刻が翌日になっていた場合、
たとえば開始時刻が「12:40」で、終了時刻が翌日の「12:30」であるとしたら、
終了時刻が翌日であると判断されていませんでした。
そこで考えたのが、開始時刻と終了時刻を、「時」「分」まるごと
分単位に修正して比較しようという考えです。
修正前・・・
//開始時刻の「時」が終了時刻の「時」を上回っていたら翌日と判断し、終了時刻に1日分のUNIX時間(GAS基準)を追加。 if(endTimeHours < startTimeHours){ endUnixTime += 86400000; }
修正後・・・
//開始時刻が終了時刻を上回っていたら翌日と判断し、終了時刻に1日分のUNIX時間(GAS基準)を追加。 if((endTimeHours * 60) + endTimeMinutes < (startTimeHours * 60) + startTimeMinutes){ endUnixTime += 86400000; }
これで、分単位で翌日になるよう修正しました。
今後、このような計測の仕方を行う事がありそうなので、
こちらも上記のコードは関数として保存し、今後使えるようにしました。
以上のコードは、勝手に使用していただいても結構です。