まずは休日・祝日がカレンダー通りの場合です。土日と祝日が休みで、他に独自の休日はないというケースですね。
この場合は下記のスクリプトで第一営業日を取得できます。
function 今月の第一営業日を取得する()
{
//先月の月末を取得する
var 今年 = new Date().getFullYear()
var 今月 = new Date().getMonth()
var Dateオブジェクト = new Date(今年,今月,0)
//今月の1日が祝日 or 土日ならDateオブジェクトに1日足す
var UNIX時間_1日 = 1 * 24 * 60 * 60 * 1000
while(!祝日じゃない || !土日じゃない)
{
var UNIX時間_1日後 = Dateオブジェクト.getTime() + UNIX時間_1日
var Dateオブジェクト = new Date(UNIX時間_1日後)
var 祝日カレンダー = "ja.japanese#holiday@group.v.calendar.google.com";
var 祝日じゃない = CalendarApp.getCalendarById(祝日カレンダー).getEventsForDay(Dateオブジェクト).length == 0
var 土日じゃない = Dateオブジェクト.getDay() != 0 && Dateオブジェクト.getDay() != 6
}
//Dateオブジェクトが第一営業日になっている
Logger.log(Dateオブジェクト)
}
全体の流れはざっくり下記です。
それぞれの部分を解説していきます。
プログラムの中の下記の部分です。
//今月の1日を取得する
var 今年 = new Date().getFullYear()
var 今月 = new Date().getMonth()
var Dateオブジェクト = new Date(今年,今月,0)
現在の年と月を取得します。日付は0を指定すれば「1日の前の日」を取得できます。
プログラムの中の下記の部分です。
//今月の1日が祝日 or 土日ならDateオブジェクトに1日足す
var UNIX時間_1日 = 1 * 24 * 60 * 60 * 1000
このプログラムでは「土日祝日だったら次の日」を見ます。そのため「次の日」を出す必要があります。
計算はUNIX時間で行うので、UNIX時間で1日を定義しておく必要があります。
UNIX時間はミリ秒なので、1日=24時間 = 1440分 = 84400秒 = 84400000ミリ秒です。掛け算で書いた方が意味が分かりやすいので、掛け算で書いています。
プログラムの中の下記の部分です。
var UNIX時間_1日後 = Dateオブジェクト.getTime() + UNIX時間_1日
var Dateオブジェクト = new Date(UNIX時間_1日後)
繰り返しの最初で、Dateオブジェクトを1日後に設定しましょう。DateオブジェクトをUNIX時間に変換し、先程出した1日分のUNIX時間を足します。
プログラムの中の下記の部分です。
var 祝日カレンダー = "ja.japanese#holiday@group.v.calendar.google.com";
var 祝日じゃない = CalendarApp.getCalendarById(祝日カレンダー).getEventsForDay(Dateオブジェクト).length == 0
ここではGoogleカレンダーを利用します。
Googleカレンダーには日本の祝日の予定が入ったカレンダーが公式に公開されています。祝日カレンダーに今日の日付で予定が入っていれば、今日は祝日だと判定できます。
CalendarApp.getCalendarById(祝日カレンダー).getEventsForDay(Dateオブジェクト)
で、今日の予定を配列で取得できます。配列の長さが0なら、予定がない=祝日ではありません。
プログラムの中の下記の部分です。
var 土日じゃない = Dateオブジェクト.getDay() != 0 && Dateオブジェクト.getDay() != 6
getDay関数を使っています。土曜は6、日曜は0なので、どちらでもなければ土日ではありません。
while文で、土日祝日の間は3-5を繰り返します。平日になったら終了します。終了した時の日付が月の最初の平日=第一営業日です。
第一営業日は先月の月末から日付をカウントアップしていきました。最終営業日は逆に、来月の月初からカウントダウンしていく事で取得できます。 この場合は下記のスクリプトで第一営業日を取得できます。
function 今月の最終営業日を取得する()
{
//来月の1日を取得する
var 今年 = new Date().getFullYear()
var 今月 = new Date().getMonth() + 1
var Dateオブジェクト = new Date(今年,今月,1)
//今月の1日が祝日 or 土日ならDateオブジェクトに1日足す
var UNIX時間_1日 = 1 * 24 * 60 * 60 * 1000
while(!祝日じゃない || !土日じゃない)
{
var UNIX時間_1日後 = Dateオブジェクト.getTime() - UNIX時間_1日
var Dateオブジェクト = new Date(UNIX時間_1日後)
var 祝日カレンダー = "ja.japanese#holiday@group.v.calendar.google.com";
var 祝日じゃない = CalendarApp.getCalendarById(祝日カレンダー).getEventsForDay(Dateオブジェクト).length == 0
var 土日じゃない = Dateオブジェクト.getDay() != 0 && Dateオブジェクト.getDay() != 6
}
//Dateオブジェクトが最終営業日になっている
Logger.log(Dateオブジェクト)
}
下記の流れで取得する事ができます。
例えば第二営業日であれば下記の形です。
function 今月の第二営業日を取得する()
{
//来月の1日を取得する
var 今年 = new Date().getFullYear()
var 今月 = new Date().getMonth()
var Dateオブジェクト = new Date(今年,今月,0)
//今月の1日が祝日 or 土日ならDateオブジェクトに1日足す
var UNIX時間_1日 = 1 * 24 * 60 * 60 * 1000
while(!祝日じゃない || !土日じゃない)
{
var UNIX時間_1日後 = Dateオブジェクト.getTime() + UNIX時間_1日
var Dateオブジェクト = new Date(UNIX時間_1日後)
var 祝日カレンダー = "ja.japanese#holiday@group.v.calendar.google.com";
var 祝日じゃない = CalendarApp.getCalendarById(祝日カレンダー).getEventsForDay(Dateオブジェクト).length == 0
var 土日じゃない = Dateオブジェクト.getDay() != 0 && Dateオブジェクト.getDay() != 6
}
//第一営業日の次の日を取得する
var UNIX時間_1日後 = Dateオブジェクト.getTime() + UNIX時間_1日
var Dateオブジェクト = new Date(UNIX時間_1日後)
//今月の1日が祝日 or 土日ならDateオブジェクトに1日足す
var UNIX時間_1日 = 1 * 24 * 60 * 60 * 1000
while(!祝日じゃない || !土日じゃない)
{
var UNIX時間_1日後 = Dateオブジェクト.getTime() + UNIX時間_1日
var Dateオブジェクト = new Date(UNIX時間_1日後)
var 祝日カレンダー = "ja.japanese#holiday@group.v.calendar.google.com";
var 祝日じゃない = CalendarApp.getCalendarById(祝日カレンダー).getEventsForDay(Dateオブジェクト).length == 0
var 土日じゃない = Dateオブジェクト.getDay() != 0 && Dateオブジェクト.getDay() != 6
}
//Dateオブジェクトが最終営業日になっている
Logger.log(Dateオブジェクト)
}
※あえて手続き的に書いているので、適宜スマートな書き方にして下さい
ここまでは土日と祝日が休みの場合について解説しました。しかし土日休みではなかったり、会社独自の休みがあったりするケースは珍しくありません。個人単位で言えば、有給を使う日の休みも判定したい場合があるでしょう。
そして会社や個人の休日カレンダーは、自分自身で作る事ができます。
先程は祝日判定のために、Googleの作成した祝日カレンダーを使いました。同じように会社・個人の休日カレンダーを作成し、休日を判定しましょう。
まずは会社・個人の休日カレンダーをGoogleカレンダーで作成しましょう。作成後には休日の予定を登録し、カレンダーのIDを取得します。
会社・個人の休日カレンダーができたら、祝日カレンダーを参照していた部分を、休日カレンダーに変更しましょう。また土日休みもカレンダーに登録する前提で、土日判定も外しました。
function 今月の第一営業日を取得する()
{
//先月の月末を取得する
var 今年 = new Date().getFullYear()
var 今月 = new Date().getMonth()
var Dateオブジェクト = new Date(今年,今月,0)
//今月の1日が祝日 or 土日ならDateオブジェクトに1日足す
var UNIX時間_1日 = 1 * 24 * 60 * 60 * 1000
while(!休日じゃない)
{
var UNIX時間_1日後 = Dateオブジェクト.getTime() + UNIX時間_1日
var Dateオブジェクト = new Date(UNIX時間_1日後)
var 休日カレンダー = //休日カレンダーのID;
var 休日じゃない = CalendarApp.getCalendarById(休日カレンダー).getEventsForDay(Dateオブジェクト).length == 0
}
//Dateオブジェクトが第一営業日になっている
Logger.log(Dateオブジェクト)
}
同じ要領で最終営業日も取得できます。
function 今月の最終営業日を取得する()
{
//先月の月末を取得する
var 今年 = new Date().getFullYear()
var 来月 = new Date().getMonth()
var Dateオブジェクト = new Date(今年,来月,1)
//今月の1日が祝日 or 土日ならDateオブジェクトに1日足す
var UNIX時間_1日 = 1 * 24 * 60 * 60 * 1000
while(!休日じゃない)
{
var UNIX時間_1日後 = Dateオブジェクト.getTime() - UNIX時間_1日
var Dateオブジェクト = new Date(UNIX時間_1日後)
var 休日カレンダー = //休日カレンダーのID;
var 休日じゃない = CalendarApp.getCalendarById(休日カレンダー).getEventsForDay(Dateオブジェクト).length == 0
}
//Dateオブジェクトが第一営業日になっている
Logger.log(Dateオブジェクト)
}
土日を判定していない分、プログラムはこちらの方がシンプルになりました。
実際に業務の自動化を行うと、営業日を使った判定を使用する場面は非常に多いものです。また最近の自動化ブームがありますから、会社の休日をどう処理しようか悩む人は意外と多いものです。
会社の休日カレンダーがGoogleカレンダーで準備されていれば、自動化用途でもその他の用途でも便利なものです。作成してしまえば意外と喜ぶ人も多いかもしれません。