ECMA Script6(JavaScript)のnew Date()をUTCからJSTに変換する方法(AWS Lambdaで注意)

ECMA Script6(JavaScript)のnew Date()をUTCからJSTに変換する方法(AWS Lambdaで注意)

ECMA Script6(JavaScript)のnew Date()をUTCからJSTに変換する方法です。

new Date()するとUTC時間になります。

let a = new Date();
console.log(a);

結果を見てみます。

2017-12-02T08:05:52.376Z

日付出力形式のT

上記を見ると、Tという文字が年月日と時間の間に表示されています。

このTは、年月日と時間の区切りを表す意味があります。

日付出力形式のZ

上記を見ると、末尾にZという文字が表示されています。

これはUTCを意味しています。その他は+09:00と言った感じで表示されます。※TとかZとかはISOで決まっている書式となります。詳細はググってください。

UTCとJST

JSTとは簡単に言うと日本時間です。

UTCは世界協定時間みたいなもので、日本時間から9時間引いた時間がUTCになります。

UTCからJSTに変換する

new Date()でJSTのDateオブジェクトを取得するメソッドはありません。

UTCから計算してJSTに変換します。といっても9時間足すだけです。

let date = new Date();
date.setTime(date.getTime() + 1000*60*60*9);// JSTに変換
console.log(date);

これでdateの時間はJSTに変換されます。

取得するときに注意

UTCをJST時間に合わせただけなので、影響を受けるメソッドはgetUTCFullYear()やgetUTCDate()やgetUTCHours()などのUTCがつくメソッドのみとなります。

AWS Lambda上では全てUTCになる

Lambda(node.js)で、getHours()の戻り値とgetUTCHours()の戻り値は同じになります。(その他のメソッド全て) どうもAWS上では全てUTCが戻ってくるようです。 以下をindex.jsとして、ハンドラをindex.handlerにして実行してみると結果が同じであることがわかります。

exports.handler = (event, context, callback) => {
  let dt = new Date();
  console.log(dt.getFullYear());
  console.log(dt.getUTCFullYear());
  console.log(dt.getUTCDate());
  console.log(dt.getDate());
  console.log(dt.getUTCHours());
  console.log(dt.getHours());
  // TODO implement
  callback(null, 'Hello from Lambda');
};

環境変数でタイムゾーンを変更する

東京リージョンのLambdaでもUTC時間になるのですが、以下の設定を行えばタイムゾーンをローカルに変更することができます。

process.env.TZ = 'Asia/Tokyo';

getHours()メソッドなど、UTCと書かれていないメソッドはローカル時間を取得するようになります。 ※Lambda のタイムゾーンを環境変数TZで指定してはいけないっていう話

Lambda(node.js)ではmoment-timezoneを使う※サポート終了

どうも環境変数の上書きは非推奨のようなので、Lambda(node.js)ではmoment-timezoneを使ってタイムゾーンを指定すればJSTにすることができます。

const moment = require('moment-timezone');

exports.handler = async (event) => {
  const dateTimeJst = moment().tz('Asia/Tokyo').format();
  console.log(dateTimeJst);// JST
};

moment-timezoneでISO8601形式でフォーマットするには以下のようにformatメソッドに引数を指定します。

|使い方|形式|出力|

|—|—|—| |format(‘YYYYMMDDTHHmmssZ’)|YYYYMMDDTHHmmssZ|20200624T114138+09:00| |format(‘YYYYMMDDTHHmmssz’)|YYYYMMDDTHHmmssz|20200624T113848JST|

zの大文字小文字で出力が異なります。

moment同士の日付大小比較※サポート終了

moment-timezoneで日付の大小比較を行うには、isAfter,isBeforeなどを使用します。

日付の文字列をmomentの第一引数に渡して比較します。

日付A 日付B メソッド 真偽値
20200625T000001+09:00 20200630T000000+09:00 isAfter false| |20200630T000000+09:00|20200625T000001+09:00|isAfter|true| |20200625T000001+09:00|20200630T000000+09:00|isBefore|true| |20200630T000000+09:00|20200625T000001+09:00|isBefore|false

以下、例です。

moment('20200625T000001+09:00').isBefore(moment('20200630T000000+09:00'))

現在日付を求めるには以下のように記述して求めます。戻り値は文字列です。

moment().tz('Asia/Tokyo').format('yyyyMMDDTHHmmss'); // 20200702T000000+09:00
moment().tz('Asia/Tokyo').format('YYYYMMDDTHHmmss'); // 20200702T075247+09:00

formatをyyyyMMDDTHHmmssとしてしまうと、時分秒が000000となってしまうので、yyyyはYYYYにしておく必要があります。

momentでISO8601形式のチェック※サポート終了

moment-timezoneのisValidメソッドを使用して、日付の形式妥当性をチェックします。 const moment = require(‘moment-timezone’)

let bool
bool = moment('20200101T101010+09:00',moment.ISO_8601).isValid()
console.log(bool) // true
bool = moment('20200101T101010+0900',moment.ISO_8601).isValid()
console.log(bool) // true

moment.jsはサポート終了

moment.jsはサポート終了し新規開発行わずにメンテナンスモードになります。 https://momentjs.com/docs/#/-project-status/

luxon

momentの代わりとしていくつかライブラリがありますがluxonでタイムゾーン指定して正しく動作することを確認します。

import {DateTime, Duration} from 'luxon'

export async function handler(event, context) {

  const date = DateTime.now().setZone('Asia/Tokyo').toFormat('yyyy/MM/dd HH:mm:ss')
  console.log(date) 
  return {
    statusCode: 200,
    body: `Hello`
  }
}

Cloud Watch Logsのログです。

2022-08-28T23:07:17.152Z 736f0c4b-9b33-451f-904f-d1023b12c71c INFO 2022/08/29 08:07:16
↑ClowdWatchLogsの先頭はUTC、luxonが出力する日時はJSTとなっている

コメント

タイトルとURLをコピーしました