ビューワーリクエストでCloudFront FunctionsやLambda@Edgeでタイムゾーンの判定ができるのか確認してみた

ビューワーリクエストでCloudFront FunctionsやLambda@Edgeでタイムゾーンの判定ができるのか確認してみた

Clock Icon2025.07.08

ビューワーリクエストでCloudFront FunctionsやLambda@Edgeでタイムゾーンの判定ができるのか気になる

こんにちは、のんピ(@non____97)です。

皆さんはビューワーリクエストでCloudFront FunctionsやLambda@Edgeでタイムゾーンの判定ができるのか気になったことはありますか? 私はあります。

オリジンリクエストをする際でのタイムゾーンの判定は以下のようにCloudFront-Viewer-Time-Zoneを用いることで可能です。

https://dev.classmethod.jp/articles/cloudfront-geolocation-headers/

https://dev.classmethod.jp/articles/request-country-redirect/

ふと、以下記事で行なっているようなキャッシュキーの整形のためにビューワーリクエストでもタイムゾーンの判定ができるかどうか気になりました。

https://dev.classmethod.jp/articles/cloudfront-functions-lambda-edge-timezone-detection-viewer-request/

実際に試してみます。

ちなみに、Lambda@Edgeでタイムゾーンの環境変数はデフォルトUTCです。

TZ– 環境のタイムゾーン(:UTC)。実行環境はNTPを使用してシステムクロックを同期します。

Lambda 環境変数の操作 - AWS Lambda

実際に試してみます。

いきなりまとめ

  • ビューワーリクエストでCloudFront FunctionsやLambda@Edgeでタイムゾーンの判定をすることはできない

CloudFront Functions

使用するコード

まずはCloudFront Functionsから実行します。

使用するコードは以下のとおりです。

function handler(event) {
    const now = new Date();
    const timezoneOffset = now.getTimezoneOffset()

    const response = {
        statusCode: 200,
        statusDescription: 'OK',
        headers: {
            'x-date-now': { value: now.toString() },
            'x-timezone-offset': { value: timezoneOffset.toString() }
        }
    };
    return response;
}

こちらを/date/cf2のビヘイビアでビューワーリクエストで動作するように設定します。

us-east-1のCloudShellから呼び出し

それでは、まずはus-east-1のCloudShellから呼び出しをしてみます。

$ echo $AWS_REGION
us-east-1

$ date
Tue Jul  8 12:55:39 AM UTC 2025

$ cat /etc/localtime
TZif2UTCTZif2UTC
UTC0

$ curl -I https://www.non-97.net/date/cf2
HTTP/2 200 
server: CloudFront
date: Tue, 08 Jul 2025 00:57:22 GMT
content-length: 0
x-date-now: Tue Jul 08 2025 00:57:22 GMT+0000
x-timezone-offset: 0
x-cache: FunctionGeneratedResponse from cloudfront
via: 1.1 5084a25d91022b55b5acf281581c6444.cloudfront.net (CloudFront)
x-amz-cf-pop: IAD61-P1
alt-svc: h3=":443"; ma=86400
x-amz-cf-id: UtgBI2zGh2gIzr60Q--eY2Snjy6bUueC1RIEZWxh6fjgkgV_z86x0g==

$ curl -I https://www.non-97.net/date/cf2
HTTP/2 200 
server: CloudFront
date: Tue, 08 Jul 2025 00:57:39 GMT
content-length: 0
x-date-now: Tue Jul 08 2025 00:57:39 GMT+0000
x-timezone-offset: 0
x-cache: FunctionGeneratedResponse from cloudfront
via: 1.1 8696978c2d465ffc3a342761ace51d9e.cloudfront.net (CloudFront)
x-amz-cf-pop: IAD61-P1
alt-svc: h3=":443"; ma=86400
x-amz-cf-id: KFfi_Q47Dn_Rhe7qSHFs3jvgFTQfYEl8bemG03Ew4X7tQDdz5MoCDA==

x-timezone-offsetは0であり、タイムゾーンはUTCであることが分かります。

ap-northeast-1のCloudShellから呼び出し

次にap-northeast-1のCloudShellから呼び出しを行います。

$ echo $AWS_REGION
ap-northeast-1

$ date
Tue Jul  8 01:58:58 AM UTC 2025

$ cat /etc/localtime
TZif2UTCTZif2UTC
UTC0

$ curl -I https://www.non-97.net/date/cf2
HTTP/2 200 
server: CloudFront
date: Tue, 08 Jul 2025 01:59:07 GMT
content-length: 0
x-date-now: Tue Jul 08 2025 01:59:07 GMT+0000
x-timezone-offset: 0
x-cache: FunctionGeneratedResponse from cloudfront
via: 1.1 b3501c20a49de1b44e6f6541d94742b6.cloudfront.net (CloudFront)
x-amz-cf-pop: NRT12-P9
alt-svc: h3=":443"; ma=86400
x-amz-cf-id: Ny10Mct_j4-UcogaiJueljGeJ-FRDUEQ0dpL0iMZim8wPBQaofpEJg==

$ curl -I https://www.non-97.net/date/cf2
HTTP/2 200 
server: CloudFront
date: Tue, 08 Jul 2025 01:59:11 GMT
content-length: 0
x-date-now: Tue Jul 08 2025 01:59:11 GMT+0000
x-timezone-offset: 0
x-cache: FunctionGeneratedResponse from cloudfront
via: 1.1 63e796d5ab2f61effb7a6df6497d49f8.cloudfront.net (CloudFront)
x-amz-cf-pop: NRT12-P9
alt-svc: h3=":443"; ma=86400
x-amz-cf-id: KgeijqU6161GSbcAmy0t5hiGZWLl0bQi3So4A7nj2IN2up0YIS6Iag==

こちらもx-timezone-offsetは0であり、タイムゾーンはUTCであることが分かります。

自端末から呼び出し

私は日本に暮らしています。自端末からも呼び出しをしてみます。

LC_ALL=C date
Tue Jul  8 11:02:03 JST 2025

> curl -I https://www.non-97.net/date/cf2
HTTP/2 200
server: CloudFront
date: Tue, 08 Jul 2025 02:02:31 GMT
content-length: 0
x-date-now: Tue Jul 08 2025 02:02:31 GMT+0000
x-timezone-offset: 0
x-cache: FunctionGeneratedResponse from cloudfront
via: 1.1 d6a8fd11b3bf4867ce673aa444e83f86.cloudfront.net (CloudFront)
x-amz-cf-pop: NRT12-P9
alt-svc: h3=":443"; ma=86400
x-amz-cf-id: g7LUhMyBqpNh9lu-T-kEtgUZ5rwLC-1S0AiZDTejo1Zz6a7sOrkHGw==

> curl -I https://www.non-97.net/date/cf2
HTTP/2 200
server: CloudFront
date: Tue, 08 Jul 2025 02:02:38 GMT
content-length: 0
x-date-now: Tue Jul 08 2025 02:02:38 GMT+0000
x-timezone-offset: 0
x-cache: FunctionGeneratedResponse from cloudfront
via: 1.1 63e796d5ab2f61effb7a6df6497d49f8.cloudfront.net (CloudFront)
x-amz-cf-pop: NRT12-P9
alt-svc: h3=":443"; ma=86400
x-amz-cf-id: 3_HabUaARIPZSGF1-WuA_D1FW7Lzp1NcLqKfDRg-U0D4mLoIfSyM0Q==

今回もx-timezone-offsetは0であり、タイムゾーンはUTCであることが分かります。

ということで、複数のリージョン、端末から実行しても結果が変わらないことからCloudFront FunctionsではタイムゾーンはUTCで固定のようです。

Lambda@Edge

使用するコード

Lambda@Edgeでも試しましょう。使用するコードは以下のとおりです。

export const handler = async (event, context, callback) => {
  const now = new Date();
  const timezoneOffset = now.getTimezoneOffset();

  const response = {
    status: '200',
    statusDescription: 'OK',
    headers: {
      'content-type': [
        {
          key: 'Content-Type',
          value: 'application/json'
        }
      ],
      'x-date-now': [
        {
          key: 'X-Date-Now',
          value: now.toString()
        }
      ],
      'x-timezone-offset': [
        {
          key: 'X-Timezone-Offset', 
          value: timezoneOffset.toString()
        }
      ]
    }
  };
  
  callback(null, response);
};

こちらを/date/lambdaEdgeのビヘイビアでビューワーリクエストで動作するように設定します。

us-east-1のCloudShellから呼び出し

ではus-east-1のCloudShellからの呼び出しを試してみます。

$ date
Tue Jul  8 02:55:11 AM UTC 2025

$ curl -I https://www.non-97.net/date/lambdaEdge
HTTP/2 200 
content-type: application/json
content-length: 0
server: CloudFront
date: Tue, 08 Jul 2025 02:55:13 GMT
x-date-now: Tue Jul 08 2025 02:55:13 GMT+0000 (Coordinated Universal Time)
x-timezone-offset: 0
x-cache: LambdaGeneratedResponse from cloudfront
via: 1.1 030b88b6d8d9c6faf056723bb5f16078.cloudfront.net (CloudFront)
x-amz-cf-pop: IAD61-P1
alt-svc: h3=":443"; ma=86400
x-amz-cf-id: HjCnduhM3Sh4q8bjFN-EcIev8vF0qbra64yhnQd5KOrjzq6SuBTwwA==

x-timezone-offsetは0であり、タイムゾーンはUTCであることが分かります。

ap-northeast-1のCloudShellから呼び出し

ap-northeast-1のCloudShellから呼び出しを試します。

$ date
Tue Jul  8 02:55:57 AM UTC 2025

$ curl -I https://www.non-97.net/date/lambdaEdge
HTTP/2 200 
content-type: application/json
content-length: 0
server: CloudFront
date: Tue, 08 Jul 2025 02:56:04 GMT
x-date-now: Tue Jul 08 2025 02:56:04 GMT+0000 (Coordinated Universal Time)
x-timezone-offset: 0
x-cache: LambdaGeneratedResponse from cloudfront
via: 1.1 d6a8fd11b3bf4867ce673aa444e83f86.cloudfront.net (CloudFront)
x-amz-cf-pop: NRT12-P9
alt-svc: h3=":443"; ma=86400
x-amz-cf-id: kkhyyWbr31YdV0KAAS7Qlj6EUKvCMenMqFljq9xNsDWW4Q4Z4SjaQw==

こちらもx-timezone-offsetは0であり、タイムゾーンはUTCであることが分かります。

自端末から呼び出し

最後に自端末から呼び出します。

> LC_ALL=C date
Tue Jul  8 13:15:19 JST 2025

> curl -I https://www.non-97.net/date/lambdaEdge
HTTP/2 200
content-type: application/json
content-length: 0
server: CloudFront
date: Tue, 08 Jul 2025 04:15:23 GMT
x-date-now: Tue Jul 08 2025 04:15:23 GMT+0000 (Coordinated Universal Time)
x-timezone-offset: 0
x-cache: LambdaGeneratedResponse from cloudfront
via: 1.1 4b89bcf81ee0cac0bd0f3005a626d42c.cloudfront.net (CloudFront)
x-amz-cf-pop: NRT12-P9
alt-svc: h3=":443"; ma=86400
x-amz-cf-id: _M25GFET2c9TFBHd1J6QR3ZbhSHcdmOgdTs4XQQjTP96IIOiA1Il5g==

やはりx-timezone-offsetは0であり、タイムゾーンはUTCであることが分かります。

ビューワーリクエストでCloudFront FunctionsやLambda@Edgeでタイムゾーンの判定はできない

ビューワーリクエストでCloudFront FunctionsやLambda@Edgeでタイムゾーンの判定はできないことを確認しました。

無難にオリジンリクエストで判定する形が良さそうです。

キャッシュキーについてもCloudFront-Viewer-CountryCloudFront-Viewer-Time-ZoneといったCloudFront標準のジオロケーションヘッダーを用いてキャッシュをするのが良さそうです。

ビューワーの場所に基づいてキャッシュを設定する

リクエスト元の国に基づいて、オブジェクトの異なるバージョンを CloudFront でキャッシュするには、CloudFront-Viewer-Country ヘッダーをオリジンに転送するように CloudFront を設定します。CloudFront はリクエスト元の IP アドレスを 2 文字の国コードに自動的に変換します。コード順、国順に並べ替えることのできる使いやすい国コードの一覧については、Wikipedia の「ISO 3166-1 alpha-2」の項目を参照してください。

リクエストヘッダーに基づいてコンテンツをキャッシュする - Amazon CloudFront

この記事が誰かの助けになれば幸いです。

以上、クラウド事業本部 コンサルティング部の のんピ(@non____97)でした!

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.