「今日が祝日かどうか、GASで自動的に判定できないか?」——業務自動化スクリプトを組んでいると、必ずぶつかる壁がこれです。この記事では、Googleカレンダーの日本の祝日カレンダーとGASを組み合わせて、祝日・休日を完全自動判定する方法を解説します。
「休日は処理をスキップしたい」「営業日だけメールを送りたい」という要件は業務自動化でよく出てきます。手動でカレンダーを管理するのは現実的ではありません。Googleカレンダーには公式の「日本の祝日」カレンダーが存在するため、これをGASから参照することで、祝日判定を完全に自動化できます。
この記事でできること
- 指定した日付が祝日・土日・休日かどうかをGASで自動判定する
- Googleカレンダーの「日本の祝日」データをAPIで取得する
- 営業日のみスクリプトを実行するトリガー制御を実装する
- 年末年始・会社独自の休日にも対応した拡張方法を理解する
事前準備(5分)
必要なものは以下の3つだけです。特別なAPIキーや権限申請は不要で、Googleアカウントがあればすぐに始められます。
- Googleアカウント(GAS実行用)
- Google Apps Script(スプレッドシートまたはスタンドアロンプロジェクト)
- CalendarApp権限(スクリプト初回実行時に自動で許可を求められます)
Googleカレンダーの「日本の祝日」カレンダーのIDは ja.japanese#holiday@group.v.calendar.google.com です。このIDをそのままGASコードに記述すれば、外部APIへのアクセス申請なしに祝日データを取得できます。
STEP 1:祝日判定の基本関数を作る
まずはGASプロジェクトを開いて(スプレッドシートのメニュー「拡張機能」→「Apps Script」)、以下の関数を貼り付けます。この関数は日付を受け取り、その日が「祝日かどうか」をtrue/falseで返します。
/**
* 指定した日付が日本の祝日かどうかを判定する
* @param {Date} date - 判定したい日付オブジェクト
* @return {boolean} 祝日なら true
*/
function isJapaneseHoliday(date) {
const calendarId = 'ja.japanese#holiday@group.v.calendar.google.com';
const calendar = CalendarApp.getCalendarById(calendarId);
// 指定日の00:00〜23:59のイベントを取得
const startOfDay = new Date(date);
startOfDay.setHours(0, 0, 0, 0);
const endOfDay = new Date(date);
endOfDay.setHours(23, 59, 59, 999);
const events = calendar.getEvents(startOfDay, endOfDay);
return events.length > 0;
}
// テスト実行用
function testHolidayCheck() {
const testDates = [
new Date('2026-01-01'), // 元日(祝日)
new Date('2026-01-02'), // 平日
new Date('2026-03-20'), // 春分の日(祝日)
];
testDates.forEach(date => {
const result = isJapaneseHoliday(date);
console.log(`${date.toLocaleDateString('ja-JP')} : ${result ? '祝日' : '祝日ではない'}`);
});
}
testHolidayCheck 関数を実行すると、ログに「元日: 祝日」「1月2日: 祝日ではない」などと表示されます。初回実行時はカレンダーへのアクセス許可を求めるダイアログが出るので「許可」をクリックしてください。
STEP 2:「営業日かどうか」を判定する関数を作る
実務では「祝日」だけでなく「土曜・日曜」も除外した「営業日かどうか」を判定したいケースがほとんどです。STEP 1の関数を組み合わせて、土日祝を一括で判定する関数を作ります。
/**
* 指定した日付が営業日(平日かつ祝日でない)かどうかを判定する
* @param {Date} date - 判定したい日付オブジェクト
* @return {boolean} 営業日なら true
*/
function isBusinessDay(date) {
const dayOfWeek = date.getDay(); // 0=日, 1=月, ..., 6=土
// 土日チェック
if (dayOfWeek === 0 || dayOfWeek === 6) {
return false;
}
// 祝日チェック
if (isJapaneseHoliday(date)) {
return false;
}
return true;
}
/**
* 本日が営業日かどうかをチェックしてログ出力
*/
function checkTodayIsBusinessDay() {
const today = new Date();
const result = isBusinessDay(today);
if (result) {
console.log('本日は営業日です。処理を実行します。');
} else {
console.log('本日は休業日です。処理をスキップします。');
}
return result;
}
/**
* 今月の営業日をすべてリストアップする
*/
function listBusinessDaysThisMonth() {
const today = new Date();
const year = today.getFullYear();
const month = today.getMonth();
const lastDay = new Date(year, month + 1, 0).getDate();
const businessDays = [];
for (let d = 1; d <= lastDay; d++) {
const date = new Date(year, month, d);
if (isBusinessDay(date)) {
businessDays.push(date.toLocaleDateString('ja-JP'));
}
}
console.log(`今月の営業日(${businessDays.length}日):`);
console.log(businessDays.join('
'));
return businessDays;
}
STEP 3:自動化スクリプトに営業日チェックを組み込む
毎朝9時に実行する日次レポート送信スクリプトを例に、営業日チェックをどう組み込むか説明します。GASのトリガーは「毎日9時」で設定し、スクリプト内で営業日判定をすることで「平日のみ実行」を実現します。
/**
* 毎朝9時にトリガーで実行する日次レポート送信関数
* トリガー設定: 時間ベース → 日タイマー → 午前9時〜10時
*/
function sendDailyReportIfBusinessDay() {
const today = new Date();
// 営業日でなければスキップ
if (!isBusinessDay(today)) {
console.log(`${today.toLocaleDateString('ja-JP')} は休業日のためスキップ`);
return;
}
// ===== ここから通常の業務処理 =====
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('日次データ');
// スプレッドシートから昨日のデータを取得(例)
const lastRow = sheet.getLastRow();
const data = sheet.getRange(lastRow, 1, 1, 5).getValues()[0];
const subject = `【日次レポート】${today.toLocaleDateString('ja-JP')}`;
const body = `
本日の日次レポートです。
売上: ${data[1].toLocaleString()}円
件数: ${data[2]}件
目標達成率: ${data[3]}%
詳細はスプレッドシートをご確認ください。
`.trim();
GmailApp.sendEmail(
'manager@example.com',
subject,
body
);
console.log(`レポートを送信しました: ${subject}`);
}
/**
* 月末営業日にのみ実行する月次集計
* トリガー設定: 時間ベース → 日タイマー → 午後6時〜7時
*/
function runMonthlyReportOnLastBusinessDay() {
const today = new Date();
// 今日が営業日でなければスキップ
if (!isBusinessDay(today)) return;
// 明日が同じ月の営業日であればスキップ(月末営業日でない)
const tomorrow = new Date(today);
tomorrow.setDate(today.getDate() + 1);
// 翌日も同月かつ営業日ならまだ月末でない
if (tomorrow.getMonth() === today.getMonth() && isBusinessDay(tomorrow)) {
console.log('まだ月末営業日ではありません。');
return;
}
console.log('月末営業日です。月次集計を実行します。');
// ここに月次集計処理を記述
}
STEP 4:動作確認とトラブルシュート
コードを貼り付けたら、まず testHolidayCheck 関数をGASエディタから手動実行して動作を確認しましょう。ログは「表示」→「ログ」またはCtrl+Enter(Mac: Cmd+Enter)で確認できます。
トラブルシュートチェックリスト
- 「カレンダーが見つからない」エラー:CalendarAppの権限が付与されていない可能性があります。スクリプトを初回実行したとき「承認が必要です」と表示されたら、必ず「許可」をクリックしてください。
- 祝日が正しく取得できない:カレンダーIDのスペルを確認してください。正しいIDは
ja.japanese#holiday@group.v.calendar.google.comです。 - 振替休日が取得できない:Googleカレンダーの日本の祝日カレンダーには振替休日も含まれています。別途対応は不要です。
- 処理が遅い:
getCalendarByIdやgetEventsはAPI呼び出しのため1〜2秒かかります。月全体の営業日を一括チェックする場合、APIコール数が多くなります。1ヶ月分のイベントを一度に取得してキャッシュする最適化を検討してください(後述の応用参照)。
応用:さらに便利にする拡張アイデア
- 会社独自の休日を追加する:Googleカレンダーに社内向けの「会社カレンダー」を作成し、年末年始や創立記念日などを登録しておく。GAS側では複数のカレンダーIDに対してイベント取得を行い、いずれかにイベントがあれば休日と判定するよう拡張できます。
- 翌営業日・前営業日を自動計算する:「明日が休日なので今日中にリマインドを送りたい」という要件に対応するため、「次の営業日」を返す関数を作っておくと便利です。ループで翌日〜翌々日と検索し、最初にisBusinessDayがtrueになった日付を返す設計になります。
- Slack通知と組み合わせる:月末営業日検知と組み合わせてSlackに「月次締め処理のリマインド」を自動投稿する仕組みを作ることで、うっかり忘れを防止できます。GASのSlack通知連携については別記事で詳しく解説しています。
まとめ
GASとGoogleカレンダーを組み合わせることで、日本の祝日判定を外部サービスや手動管理なしに完全自動化できます。一度このコードを組み込んでおけば、毎年の祝日変更にも自動で対応してくれるため、メンテナンスコストがほぼゼロになるのが最大のメリットです。
- Googleカレンダーの祝日カレンダーID(
ja.japanese#holiday@group.v.calendar.google.com)をGASから直接参照することで、APIキー不要で祝日データを取得できる isBusinessDay()関数で土日+祝日を一括判定し、業務処理の先頭に置くだけで「営業日限定実行」が実現できる- 会社独自カレンダーを追加することで年末年始や特別休暇にも対応できる
- 月末営業日の自動検知とSlack通知を組み合わせると、月次締め処理のリマインド自動化が実現できる
「このコードを自社の業務に合わせてカスタマイズしたい」「もっと複雑な営業日ロジックが必要」という場合は、お気軽にお問い合わせください。


コメントを残す