GASを使用してGoogleカレンダーに最終営業日を追加する方法

カレンダーに毎月の最終営業日を追加できない

Googleカレンダーには毎月の最終営業日を追加できる機能がありません。

「毎月 最終金曜日」や「毎月 31日」の追加はできますが、これでは最終営業日の追加はできません。

毎月の最終営業日とは

毎月の最終営業日の定義は以下の通りです。

  • 月の最後の平日である
  • 土日および祝日ではない
  • 年末や会社独自の休みの期間ではない

例えば2023年12月の場合は年末年始の休みが12/29から1/3の場合は、12月28日(木)がその月の最終営業日ということになります。

最終営業日は企業によっては「会計処理の締め日」や「その月の業務報告日」になっていることがあります。

また、最終営業日はタイムシートなどの勤怠管理記録の提出日になっていることも多いです。

このような重要な日であるのにも関わらず、Googleカレンダーでは最終営業日の追加はできません。

しかし、Google Apps Script (以下GAS)を使用すれば前述のような条件の最終営業日の予定を追加できます。

GASを使用するにはApps Scriptエディタでコードを書いて、addLastBusinessDaysを選択して「実行」を選択します。

GASを使用してGoogleカレンダーに最終営業日を追加する方法

addLastBusinessDays()を実行するとGoogleカレンダーに下図のように予定が追加されます。

addLastBusinessDays()の実行結果

毎月の最終営業日するGAS

毎月の最終営業日するGASは以下の通りです。

まず【カレンダーID】の部分にカレンダーIDを入力します。

カレンダーIDはGoogleカレンダーの「カレンダーの設定」で確認できます。

次にyearEndVacationDateに12月の年末の休みの開始日を入れて、addLastBusinessDays()を実行すれば「最終営業日」という予定を毎月の最終営業日に追加できます。

// 実行する関数はaddLastBusinessDays()
const calendarId = '【カレンダーID】'
const yearEndVacationDate = 29

function isSatSun(date) {
  return date.getDay() === 0 || date.getDay() === 6
}

function isHoliday(date) {
  const calendarId = 'ja.japanese#holiday@group.v.calendar.google.com'
  const calendar = CalendarApp.getCalendarById(calendarId)
  const events = calendar.getEventsForDay(date)

  return events.length > 0
}

function isYearEndVacation(date) {
  const currentMonth = date.getMonth() + 1
  const currentDate = date.getDate()

  return currentMonth === 12 && currentDate >= yearEndVacationDate
}

function addLastBusinessDays() {
  const calendar = CalendarApp.getCalendarById(calendarId)
  const today = new Date()
  const setYearTerms = 1
  let currentYear = today.getFullYear()

  for (let i = 0; i <= setYearTerms; i++) {
    for (let month = 0; month <= 11; month++) {
      addLastBusinessDayForMonth(calendar, currentYear + i, month)
    }
  }
}

function addLastBusinessDayForMonth(calendar, year, month) {
  const lastDayOfMonth = new Date(year, month + 1, 0)
  const title = '最終営業日'

  while (
    isSatSun(lastDayOfMonth) ||
    isHoliday(lastDayOfMonth) ||
    isYearEndVacation(lastDayOfMonth)
  ) {
    lastDayOfMonth.setDate(lastDayOfMonth.getDate() - 1)
  }

  const events = calendar.getEventsForDay(lastDayOfMonth)
  const isEventAlreadyCreated = events.some((event) => {
    return event.getTitle() === title
  })

  if (!isEventAlreadyCreated) {
    calendar.createAllDayEvent(title, lastDayOfMonth)
  }
}

毎月の最終営業日するGASの解説

isSatSun

引数で日付を受け取って、土曜または日曜か判定します。

isHoliday

「日本の祝日」のカレンダーIDから祝日の日付一覧を取得して、祝日か判定します。

isYearEndVacation

年末の休みの期間内か判定します。

「yearEndVacationDate = 29」の場合は12/29から12/31が年末の休みだと判定されます。

addLastBusinessDays

カレンダーIDを読み込んで月ごとに予定を追加します。

GASで手動実行するのはaddLastBusinessDays()です。

setYearTermsの定数で今年から何年先までに「最終営業日」の予定を追加するか設定できます。

「setYearTerms = 9」なら10年分の予定を追加します。

addLastBusinessDayForMonth

月の何日に予定を入れるか判定して、判定結果から「最終営業日」という予定を追加します。

isEventAlreadyCreatedは同じ名前の予定がすでにないか判定しています。

IT企業のタイムシート提出日は15日と最終営業日

IT企業の場合、タイムシート提出日は15日と最終営業日になっていることが多いです。

そのため、addLastBusinessDayForMonth部分のコードは以下のように書き換えて、15日 (土日祝なら前日)にも予定が追加されるようにしたほうが良いでしょう。

※ コードの最適化のため、findLastBusinessDay と isEventCreated の関数も追加しています。

function findLastBusinessDay(date) {
  while (isSatSun(date) || isHoliday(date) || isYearEndVacation(date)) {
    date.setDate(date.getDate() - 1)
  }
  return date
}

function isEventCreated(calendar, date, title) {
  const events = calendar.getEventsForDay(date)
  return events.some((event) => event.getTitle() === title)
}

function addLastBusinessDayForMonth(calendar, year, month) {
  const middleDayOfMonth = new Date(year, month, 15)
  const lastDayOfMonth = new Date(year, month + 1, 0)
  const title = 'タイムシート提出日'
  const businessDayMid = findLastBusinessDay(middleDayOfMonth)
  const businessDayLast = findLastBusinessDay(lastDayOfMonth)

  if (!isEventCreated(calendar, businessDayMid, title)) {
    calendar.createAllDayEvent(title, businessDayMid)
  }

  if (!isEventCreated(calendar, businessDayLast, title)) {
    calendar.createAllDayEvent(title, businessDayLast)
  }
}

最終営業日やタイムシートの提出日などはカレンダーに予定を追加していないと気づかない可能性が高くなってしまいます。

そのため、記事に記載したGASで追加しておくことをオススメします。