導入
NestJSを使用して個人開発を進めています。
ある日、レスポンスの確認をしている最中にこのように思いました。
「日本時間じゃないのウザいな」
※updated_at, created_atカラムです。
緊急でもなく、重要でもないですが、息抜きがてら触ってみることに。
ということで、timezoneを設定しようと考えた次第です。
自分は今までLaravelを多く使用してきました。
Laravelでは、非常に簡単にtimezoneを設定できます。
そのため、すぐ設定し終わるだろうと思っていました。
だがまさかできないとは!
そんなフレームワークあるのかとまで思いました。
NestJSにtimezoneを設定する機能はなく、プログラムに時間操作を実装するしかないようです。
バッチ処理なんかはダルそうですね。
「それでも!NestJSの可能性を、俺は信じたい!」
(ガンダムUC、パチンカスなら分かる)
とりあえず取り組んでみたこと
データベースのtimezone
NestJSのtimezoneは一旦諦めて、データベースのtimezoneに注目してみました。
ちなみにPostgreSQLです。
以下のコマンドでログイン後、timezoneのセッティング
psql -U ユーザ名 -d データベース名
SET timezone TO 'Asia/Tokyo';
timezoneの変更後も改善されませんでした。
どうやらデータベースのtimezoneは原因ではないようです。
ORMのtimezone
ORMによる影響も考えました。
なぜなら、.schema.prismaというファイルでテーブル仕様を定義するためです。
ちなみに、Prismaはこの.schema.prismaを読み込んで、すべてを実行するSQLを作り、実行します
updated_at, created_atは以下のように定義しています。
updated_at DateTime @default(now())
created_at DateTime @default(now())
2カラムだけを載せています。
DateTime
は型、@default(now())
はデフォルト値です。
ここはORMで生成されているので、ORMが原因なのではと考えました。
ですが、僕が使用しているPrisma ORMにはtimezoneを設定することができないようでした。
これもかい。
これができれば、最も楽だと思うのですが。
やはり、NestJSやPrismaが日本で流行らないのもそれなりの理由があるようですね。
まあ僕は使いますが、
解決策
上述では、デフォルト値をORMから生成していると述べました。
つまりこれをデータベース側から生成すればよいわけです。
PostgreSQLではtimezoneを設定できました。
以下のように.schema.prismaを編集しました。
updated_at DateTime @default(dbgenerated("NOW()"))
created_at DateTime @default(dbgenerated("NOW()"))
デフォルト値の生成をORMではなく、データベースに委ねるという意味です。
これで、データベースに入る時刻はデフォルトで日本時間となりました。
懸念
バッチ処理など、バックエンドのアプリケーションベースで時刻が必要になる場合にはこの手は使えません。
9時間足すという脳筋処理や、ミドルウェアによる処理などが考えられるかと思います。
ミドルウェアによる処理も実装していこうかな、おもしろそう。
また、ほかの記事を見てみると、Node.jsにはtimezoneを設定できるようです。
それでNestJSに設定できないなんてことあるか?と思いながら、、、
こっちも探ってみようかな
個人開発って楽しい
結構楽しいですね、勉強にもなります。
転職にも有利になるかな、とも思いながら頑張っています。
(新卒で転職考えてるのは内緒で)