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となっている
KHI入社して退社。今はCONFRAGEで正社員です。関西で140-170/80~120万から受け付けております^^
得意技はJS(ES6),Java,AWSの大体のリソースです
コメントはやさしくお願いいたします^^
座右の銘は、「狭き門より入れ」「願わくは、我に七難八苦を与えたまえ」です^^
コメント