0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

CloudSchedulerで毎月第一営業日に実行する

Posted at

はじめに

Cloud Schedulerで、毎月第一月曜日とか毎月第一営業日とかにジョブを実行 (Pub/Subトピックにメッセージを送信) する方法が分からなかったので、備忘録として残しておく。
ドキュメントには、

Unix cron 形式でスケジュールを定義して、1 日に複数回ジョブを実行したり、1 年のうちの特定の日や月にジョブを実行したりできます。

と書かれてある。
が、cronの仕様だと、同時に 日にち曜日 の指定をすると、
ANDではなくOR条件になるみたいなので一筋縄ではいかなさそう。

第一営業日を判定する関数の作成

isFirstBusinessDayOfMonth.ts
const MONTHS = {
    JAN: 0,
    FEB: 1,
    MAR: 2,
    APR: 3,
    MAY: 4,
    JUN: 5,
    JUL: 6,
    AUG: 7,
    SEP: 8,
    OCT: 9,
    NOV: 10,
    DEC: 11,
} as const;

const NATIONAL_HOLIDAYS = [
    new Date(2023, MONTHS.JAN, 1), // 元日
    new Date(2023, MONTHS.JAN, 2), // 振替休日
      new Date(2023, MONTHS.JAN, 9), // 成人の日
      new Date(2023, MONTHS.FEB, 11), // 建国記念の日
    new Date(2023, MONTHS.FEB, 23), // 天皇誕生日
    new Date(2023, MONTHS.MAR, 21), // 春分の日
    new Date(2023, MONTHS.APR, 29), // 昭和の日
    new Date(2023, MONTHS.MAY, 3), // 憲法記念日
    new Date(2023, MONTHS.MAY, 4), // みどりの日
    new Date(2023, MONTHS.MAY, 5), // こどもの日
    new Date(2023, MONTHS.JUL, 17), // 海の日
    new Date(2023, MONTHS.AUG, 11), // 山の日
    new Date(2023, MONTHS.SEP, 18), // 敬老の日
    new Date(2023, MONTHS.SEP, 23), // 秋分の日
    new Date(2023, MONTHS.OCT, 9), // スポーツの日
    new Date(2023, MONTHS.NOV, 3), // 文化の日
    new Date(2023, MONTHS.NOV, 23), // 勤労感謝の日
];

const isSaturday = (date: Date): boolean => date.getDay() === 6;
const isSunday = (date: Date): boolean => date.getDay() === 0;
const isNationalHoliday = (date: Date): boolean => NATIONAL_HOLIDAYS.includes(date);

export const isFirstBusinessDayOfMonth = (date: Date): boolean => {
    let firstBusinessDayOfMonth = new Date(
        date.getFullYear(),
        date.getMonth(),
        1
    );
    
    while (
        isSaturday(firstBusinessDayOfMonth) ||
        isSunday(firstBusinessDayOfMonth) ||
        isNationalHoliday(firstBusinessDayOfMonth)
    ) {
        firstBusinessDayOfMonth = new Date(
            firstBusinessDayOfMonth.getFullYear(),
            firstBusinessDayOfMonth.getMonth(),
            firstBusinessDayOfMonth.getDate() + 1
        );
    }

    return (
        date.getFullYear() === firstBusinessDayOfMonth.getFullYear() &&
        date.getMonth() === firstBusinessDayOfMonth.getMonth() &&
        date.getDate() === firstBusinessDayOfMonth.getDate()
    );
};

スケジュールの指定

index.ts
import * as functions from 'firebase-functions';

import { isFirstBusinessDayOfMonth } from './your/path';

export const someFuncExec = functions
    .region('asia-northeast1')
    .runWith({
        memory: '1GB',
        timeoutSeconds: 300,
     })
    .pubsub.schedule('0 9 * * 1-5') // ここでは複雑な指定ができないため、平日9:00に実行するように指定
    .timeZone('Asia/Tokyo')
    .onRun(() => {
        const today = new Date();
        if (!isFirstBusinessDayOfMonth(today)) { // ここで先ほど作った関数を利用し、第一営業日じゃなかったら実行をスキップする
            return Promise.resolve();      
        } 
        return handleSomeFunc();
    });

scheduler-pubsub-func.png

以上、CloudSchedulerで毎月第一営業日にジョブを実行する方法の備忘録でした。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?