AWS Lambda関数上でDayjsを使って現在日時と特定日時の比較をしてみた

2021.11.18

こんにちは、CX事業本部 IoT事業部の若槻です。

今回は、AWS Lambda関数上でDayjsを使って現在日時と特定日時の比較をしてみました。

Dayjsとは

Dayjsは、日付や時刻の操作を行えるJavaScriptライブラリです。かつて日時操作でよく使われていたMoment.jsと互換性のあるAPIを提供していながら、ライブラリの軽量化が行われています。

そしてDayjsにおける日時の比較は以下のモジュールを使用することにより可能です。

  • isBefore()
  • isSame()
  • isAfter()
  • isSameOrBefore()
  • isSameOrAfter()
  • isBetween()

それぞれの使い方は下記にまとまっています。

ハンドラーの作成、Jestでのテスト

下記のような{comparison: '{日時}'}というイベントの{日時}(JST)が現在日時より30分以内であるか?を判定するLambda関数のハンドラーをTypeScriptで作りました。比較にはisAfter()を使用しています。

src/lambda/handlers/sampleHandler.ts

import dayjs = require('dayjs');
import timezone = require('dayjs/plugin/timezone');
import utc = require('dayjs/plugin/utc');

dayjs.extend(utc);
dayjs.extend(timezone);
dayjs.tz.setDefault('Asia/Tokyo');

export const handler = async (event: any): Promise<Boolean> => {
  const now = dayjs().tz();
  const comparison = dayjs.tz(event.comparison);

  console.log(`now: ${now.format()}`);
  console.log(`comparison: ${comparison.format()}`);

  return comparison.add(30, 'm').isAfter(now);
};

そしてこのコードをローカルでテストするために以下のJestのテストコードを作成しました。

test/sampleHandler.test.ts

import { handler } from '../src/lambda/handlers/sampleHandler';

import dayjs = require('dayjs');
import timezone = require('dayjs/plugin/timezone');
import utc = require('dayjs/plugin/utc');

dayjs.extend(utc);
dayjs.extend(timezone);
dayjs.tz.setDefault('Asia/Tokyo');

const now = dayjs().tz();

test('handler true', async (): Promise<void> => {
  const response = handler({
    //現在時刻より5分前の日時を指定
    comparison: now.subtract(5, 'm').format('YYYY/MM/DD HH:mm:ss'),
  });

  //comparisonが現在時刻より30分以内なのでパス
  expect(response).toBeTruthy;
});

test('handler false', async (): Promise<void> => {
  const response = handler({
    //現在時刻より35分以内の日時を指定
    comparison: now.subtract(5, 'm').format('YYYY/MM/DD HH:mm:ss'),
  });

  //comparisonが現在時刻より30分以前なのでパス
  expect(response).toBeFalsy;
});

Jestでのテストを実行すると、いずれのテストもパスしました。

$ npx jest
 PASS  test/sampleHandler.test.ts
  ✓ handler true (25 ms)
  ✓ handler false (2 ms)

  console.log
    now: 2021-11-19T00:37:59+09:00

      at Object.<anonymous>.exports.handler (src/lambda/handlers/sampleHandler.ts:14:11)

  console.log
    comparison: 2021-11-19T00:32:59+09:00

      at Object.<anonymous>.exports.handler (src/lambda/handlers/sampleHandler.ts:15:11)

  console.log
    now: 2021-11-19T00:37:59+09:00

      at Object.<anonymous>.exports.handler (src/lambda/handlers/sampleHandler.ts:14:11)

  console.log
    comparison: 2021-11-19T00:32:59+09:00

      at Object.<anonymous>.exports.handler (src/lambda/handlers/sampleHandler.ts:15:11)

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        2.59 s, estimated 3 s
Ran all test suites.

AWS Lambdaにデプロイ

下記のようなCDKコードでLambda関数をデプロイします。

lib/aws-cdk-app-stack.ts

import * as cdk from '@aws-cdk/core';
import * as lambdaNodejs from '@aws-cdk/aws-lambda-nodejs';

export class AwsCdkAppStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    new lambdaNodejs.NodejsFunction(this, 'sampleFunc', {
      entry: './src/lambda/handlers/sampleHandler.ts',
      handler: 'handler',
    });
  }
}

実行時の時間(2021/11/19 00:21頃)より30分以内の日時を入力で指定してLambda関数を実行してみます。

{ 
  "comparison": "2021/11/19 00:20:00"
}

すると結果はtrueとなりました。期待通りの動作です。

true

START RequestId: 625ea891-a4e0-4097-a80f-ecd8ccd57ecd Version: $LATEST
2021-11-18T15:21:40.049Z	625ea891-a4e0-4097-a80f-ecd8ccd57ecd	INFO	now: 2021-11-19T00:19:49+09:00
2021-11-18T15:21:40.050Z	625ea891-a4e0-4097-a80f-ecd8ccd57ecd	INFO	comparison: 2021-11-19T00:20:00+09:00
END RequestId: 625ea891-a4e0-4097-a80f-ecd8ccd57ecd
REPORT RequestId: 625ea891-a4e0-4097-a80f-ecd8ccd57ecd	Duration: 51.99 ms	Billed Duration: 52 ms	Memory Size: 128 MB	Max Memory Used: 66 MB

実行時の時間(2021/11/19 00:21頃)より30分以前の日時を入力で指定してLambda関数を実行してみます。

{ 
  "comparison": "2021/11/18 23:00:00"
}

すると結果はfalseとなりました。これも期待通りの動作です。

false

START RequestId: e69a2009-eb7f-4176-905f-65d3b529b1d4 Version: $LATEST
2021-11-18T15:22:09.069Z	e69a2009-eb7f-4176-905f-65d3b529b1d4	INFO	now: 2021-11-19T00:19:49+09:00
2021-11-18T15:22:09.069Z	e69a2009-eb7f-4176-905f-65d3b529b1d4	INFO	comparison: 2021-11-18T23:00:00+09:00
END RequestId: e69a2009-eb7f-4176-905f-65d3b529b1d4
REPORT RequestId: e69a2009-eb7f-4176-905f-65d3b529b1d4	Duration: 1.84 ms	Billed Duration: 2 ms	Memory Size: 128 MB	Max Memory Used: 66 MB

おわりに

AWS Lambda関数上でDayjsを使って現在日時と特定日時の比較をしてみました。

Dayjsは最初タイムゾーンの指定で少しハマりましたが、なんとかなって良かったです。

参考

以上