GASで祝日・営業日を判定して
自動処理する方法

「土日祝は処理を止めたい」「支払期日を3営業日後にしたい」——そんな要件を、Googleの祝日カレンダー(Googleが公開する日本の祝日データ)を使って動くコードで実装する方法を解説します。

|対象: GAS / 祝日判定 / 営業日計算

Table of Contents

なぜ営業日判定が必要になるのか

業務の自動化では「土日祝は動かしたくない」「営業日ベースで日付を数えたい」という要件が頻繁に出てきます。 単純に曜日だけで判定すると祝日を見逃し、逆に祝日リストを自前で毎年更新するのは手間がかかります。 GASなら、Googleが公開している祝日カレンダーを参照するだけで、メンテナンス不要の営業日判定が作れます。

定期処理の抑制

日次バッチや通知を、土日祝は止めて営業日だけ実行したい

支払期日の算出

請求書の支払期限を「発行日から◯営業日後」で自動計算したい

締め日の処理

毎月の最終営業日にレポートや締め処理を走らせたい

SLAの期限管理

問い合わせ対応期限を営業日ベースでカウントしたい

Googleの祝日カレンダーで祝日を判定する

まずは祝日判定です。Googleは「日本の祝日」カレンダーを公開しており、CalendarApp.getCalendarById()(IDを指定してカレンダーを取得するGASのメソッド)で読み込めます。 その日にイベント(=祝日)があるかをgetEventsForDay()で調べるだけです。祝日データはGoogle側で毎年更新されるため、自前で日付を管理する必要はありません。

// 日本の祝日カレンダー(Googleが公開している公式カレンダー)
const HOLIDAY_CALENDAR_ID =
  "ja.japanese#holiday@group.v.calendar.google.com";

// その日が祝日かどうかを判定する
function isHoliday(date) {
  const calendar = CalendarApp.getCalendarById(HOLIDAY_CALENDAR_ID);
  if (!calendar) {
    throw new Error("祝日カレンダーを取得できませんでした");
  }
  const events = calendar.getEventsForDay(date);
  return events.length > 0;
}

※ 初回実行時にカレンダーへのアクセス許可を求められます。承認すると、以降は自動で参照できます。

土日+祝日をまとめた営業日判定関数

次に、週末(土日)の判定と祝日判定を組み合わせて「営業日かどうか」を一つの関数にまとめます。getDay()(曜日を0〜6で返すメソッド)で土日を除外し、祝日でもなければ営業日とします。

// 土日を判定する(0=日曜, 6=土曜)
function isWeekend(date) {
  const day = date.getDay();
  return day === 0 || day === 6;
}

// 営業日かどうか(土日でも祝日でもなければ営業日)
function isBusinessDay(date) {
  return !isWeekend(date) && !isHoliday(date);
}

// 使用例
function checkToday() {
  const today = new Date();
  if (isBusinessDay(today)) {
    Logger.log("今日は営業日です");
  } else {
    Logger.log("今日は休業日です");
  }
}

N営業日後の日付を計算する

「発行日から3営業日後を支払期日にする」といった計算は、1日ずつ日付を進めながら営業日だけを数えていくと確実です。 土日祝は自動でスキップされるので、カレンダー通りの正しい期日が求められます。

// 指定日からN営業日後の日付を返す(土日祝をスキップ)
function addBusinessDays(startDate, businessDays) {
  const result = new Date(startDate);
  let added = 0;

  while (added < businessDays) {
    result.setDate(result.getDate() + 1); // 1日進める
    if (isBusinessDay(result)) {
      added += 1;
    }
  }
  return result;
}

// 使用例: 今日から3営業日後(例: 支払期日の算出)
function calcDueDate() {
  const due = addBusinessDays(new Date(), 3);
  const text = Utilities.formatDate(due, "Asia/Tokyo", "yyyy/MM/dd");
  Logger.log("支払期日: " + text);
}

月末営業日(締め日)を求める

月次の締め処理では「その月の最終営業日」がよく使われます。new Date(year, month, 0)で当月末日を取り、そこから営業日が見つかるまで1日ずつ遡ります。

// その月の「最終営業日」を返す
function getLastBusinessDayOfMonth(year, month) {
  // month は 1〜12。翌月0日 = 当月末日
  const date = new Date(year, month, 0);

  // 末日から遡り、最初に見つかった営業日を返す
  while (!isBusinessDay(date)) {
    date.setDate(date.getDate() - 1);
  }
  return date;
}

// 使用例: 2026年7月の最終営業日
function checkMonthEnd() {
  const day = getLastBusinessDayOfMonth(2026, 7);
  Logger.log(Utilities.formatDate(day, "Asia/Tokyo", "yyyy/MM/dd"));
}

祝日をまとめて取得して高速化する

祝日カレンダーへの問い合わせは外部アクセスのため、多くの日付を1日ずつ判定すると時間がかかります。 大量の日付を扱う場合は、1年分の祝日を一度に取得してSetに入れておき、以降はメモリ上で判定すると大幅に速くなります。

// 1年分の祝日をまとめて取得し、Setにして高速判定する
function buildHolidaySet(year) {
  const calendar = CalendarApp.getCalendarById(HOLIDAY_CALENDAR_ID);
  const start = new Date(year, 0, 1);
  const end = new Date(year + 1, 0, 1);
  const events = calendar.getEvents(start, end);

  const set = new Set();
  events.forEach((event) => {
    const key = Utilities.formatDate(
      event.getAllDayStartDate(),
      "Asia/Tokyo",
      "yyyy-MM-dd"
    );
    set.add(key);
  });
  return set;
}

// 事前に作ったSetを使えばカレンダーへの問い合わせは1回で済む
function isBusinessDayFast(date, holidaySet) {
  if (isWeekend(date)) return false;
  const key = Utilities.formatDate(date, "Asia/Tokyo", "yyyy-MM-dd");
  return !holidaySet.has(key);
}

// 使用例: 7月の営業日だけをログに出す
function listBusinessDays() {
  const holidays = buildHolidaySet(2026);
  for (let d = 1; d <= 31; d++) {
    const date = new Date(2026, 6, d); // 6 = 7月
    if (isBusinessDayFast(date, holidays)) {
      Logger.log(Utilities.formatDate(date, "Asia/Tokyo", "yyyy/MM/dd"));
    }
  }
}

営業日だけトリガーを動かす設計

GASの時間主導トリガーは「毎日8時」のように曜日を問わず起動します。 そのため、処理の冒頭で営業日かどうかを確認し、休業日ならreturnで早めに抜ける設計にするのが定番です。

// 毎朝トリガーで起動し、営業日だけ本処理を実行する
function dailyJob() {
  const today = new Date();
  if (!isBusinessDay(today)) {
    Logger.log("休業日のためスキップしました");
    return; // 土日祝は何もしない
  }

  // ここに営業日だけ動かしたい処理を書く
  sendMorningReport();
}

// 毎朝8時に実行するトリガーを作成
function createDailyTrigger() {
  ScriptApp.newTrigger("dailyJob")
    .timeBased()
    .everyDays(1)
    .atHour(8)
    .create();
}

実務での注意点

1. タイムゾーンを固定する

日付の文字列化にはUtilities.formatDate()で必ず「Asia/Tokyo」を指定します。スクリプトのタイムゾーン設定によっては、深夜帯の日付が1日ずれることがあるためです。

2. 振替休日・国民の休日も自動で入る

Googleの祝日カレンダーには、振替休日や国民の休日も祝日イベントとして含まれます。 そのため個別に判定を書かなくても、これらは自動的に休業日として扱われます。

3. 会社独自の休業日は別管理にする

年末年始や創立記念日など、国の祝日ではない休業日は祝日カレンダーには入りません。 独自休業日の一覧を配列やスプレッドシートで持ち、営業日判定に加える形で対応します。

まとめ

GASの営業日判定は、Googleの祝日カレンダーと曜日判定を組み合わせるだけでメンテナンス不要に作れます。 N営業日後の計算や月末営業日の算出、営業日だけ動くトリガー設計まで押さえておけば、 請求・締め・通知といった日付が絡む業務を安定して自動化できます。大量判定では祝日のまとめ取得でしっかり高速化しましょう。

よくある質問

Googleが公開している「日本の祝日」カレンダー(カレンダーID: ja.japanese#holiday@group.v.calendar.google.com)をCalendarApp.getCalendarById()で参照し、getEventsForDay()でその日にイベント(祝日)があるかを調べます。祝日データはGoogle側で毎年更新されるため、自前で日付の一覧を管理する必要がありません。

できます。getDay()が0(日曜)または6(土曜)かどうかで週末を判定し、加えて祝日カレンダーにイベントがあるかを調べます。どちらかに該当すれば休業日、どちらにも該当しなければ営業日、という一つの関数にまとめておくと使い回しやすくなります。

できます。開始日から1日ずつ日付を進め、営業日だったらカウントを1つ増やし、指定した営業日数に達したらその日付を返します。土日祝を自動でスキップするので、請求書の支払期日や対応期限の算出に使えます。

祝日カレンダーへの問い合わせは外部アクセスのため、大量の日付を判定すると時間がかかります。年単位で祝日をまとめて取得してSetに入れておく、CacheServiceやPropertiesServiceに判定結果を保存するなどのキャッシュを挟むと大幅に高速化できます。

含められます。祝日カレンダーとは別に、独自の休業日を配列やスプレッドシートで管理し、営業日判定の中でその一覧にも該当しないかをチェックします。祝日・週末・独自休業日の3つを合わせて「休業日」と定義すれば実務に即した判定になります。

GAS開発・業務Webシステムを
相談する。

営業日判定のほかにも、締め処理・帳票出力・定期通知など、日付が絡む業務の自動化をGAS開発でご相談いただけます。

GAS開発の対応範囲を見る