Nest.Js에서 한국시간 기준 스케쥴링할 때 주의점 (With Timezone)

Posted by , January 29, 2023
NestJsTimezone
Series ofNestJs

thumbnail

NestJs에서 스케쥴링...

현재 하고 있는 프로젝트에서 스케쥴링이 필요하여 구현했었다.
그런데 스케쥴링을 돌렸는데 뭔가 시간이 안맞게 돌아간다고 해야 하나?

분과 초단위는 잘 도는데 시간대가 좀 안맞았다.
그래서 테스트를 하고 자료를 찾다가 원인을 알게되었다...


원인?

이유는 바로 TimeZone 문제였다.

내가 구현한 코드는 다음과 같이 구성되어 있다.

@Cron("0 0-10 0-23 * * 0-5", { name: "UpdateDataSchedule"})
async cron4Time4Data() {
    const result = await this.taskSchedulerService.UpdateData();

    if (result) {
        this.stop4CronJob("UpdateDataSchedule");
    }
}

일요일에서 금요일까지 자정에서 11시까지 도는 스케쥴러다.
근데 로깅을 찍어보고 해봐도 뭔가 이상했다.

export interface CronOptions {
  /**
   * Specify the name of your cron job. This will allow to inject your cron job reference through `@InjectCronRef`.
   */
  name?: string
  /**
   * Specify the timezone for the execution. This will modify the actual time relative to your timezone. If the timezone is invalid, an error is thrown. You can check all timezones available at [Moment Timezone Website](http://momentjs.com/timezone/). Probably don't use both ```timeZone``` and ```utcOffset``` together or weird things may happen.
   */
  timeZone?: string
  /**
   * This allows you to specify the offset of your timezone rather than using the ```timeZone``` param. Probably don't use both ```timeZone``` and ```utcOffset``` together or weird things may happen.
   */
  utcOffset?: string | number
  /**
   * If you have code that keeps the event loop running and want to stop the node process when that finishes regardless of the state of your cronjob, you can do so making use of this parameter. This is off by default and cron will run as if it needs to control the event loop. For more information take a look at [timers#timers_timeout_unref](https://nodejs.org/api/timers.html#timers_timeout_unref) from the NodeJS docs.
   */
  unrefTimeout?: boolean
}

/**
 * Creates a scheduled job.
 * @param cronTime The time to fire off your job. This can be in the form of cron syntax or a JS ```Date``` object.
 * @param options Job execution options.
 */
export declare function Cron(
  cronTime: string | Date,
  options?: CronOptions
): MethodDecorator

@Cron의 함수 형태인데 뒤에 옵션이 수상했다.
위에 선언된 속성 중 timezone이 옵셔널로 들어오는데 이게 문제였었다.

아무것도 선언을 안해주면 그냥 UTC 시간대가 적용된다.
그래서 이걸 아래와 같이 timezone을 선언해주면 아주 간단하게 해결되는 문제였다.

@Cron("0 0-10 0-23 * * 0-5", { name: "UpdateDataSchedule", timeZone: "Asia/Seoul"})
....

이렇게 해주니 한국시 기준으로 잘 동작하였다.

참고