0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

🕰️ 【n8n/JS】Date型で「9時間ズレる」呪いを解くためのメモ【JST vs UTC】

Posted at

こんにちは😊
株式会社プロドウガ@YushiYamamotoです!
らくらくサイトの開発・運営を担当しながら、React.js・Next.js専門のフリーランスエンジニアとしても活動しています❗️

今回は、n8nやJavaScript(Node.js)を触り始めた人が100%の確率で遭遇すると言っても過言ではない、「時間が9時間ズレる問題」についての備忘録です。

「朝9時に実行したはずなのに、ログを見たら深夜0時になっている…👻」
「今日の日付でファイルを作ったはずが、昨日の日付になっている…📅」

こんな経験はありませんか?それはバグではなく、タイムゾーンの呪いです。サクッと解呪する方法をまとめました。

🌏 なぜ9時間ズレるのか?

結論から言うと、n8n(および多くのサーバー環境)の標準時間は「UTC(協定世界時)」だからです。

私たち日本人が生活している「JST(日本標準時)」は、UTCよりも 9時間進んで います。

  • UTC: 12:00
  • JST: 21:00 (UTC + 9時間)

プログラム上で new Date() をして取得されるのは、基本的にUTC基準のタイムスタンプです。これをそのまま日本感覚で表示しようとすると、「あれ?9時間遅れてる?」という現象が発生します。

🛠️ 解決策1:n8n標準の「Luxon」を使う(推奨)

n8nには、日付操作の強力なライブラリである Luxon が組み込まれています。
Codeノード(JavaScript)内では、わざわざ npm install しなくても、n8n独自の変数 $nowDateTime オブジェクトを使って簡単に変換できます。

最も簡単な書き方

// 現在時刻をJST(東京)のタイムゾーンでフォーマットする
const jstTime = $now.setZone('Asia/Tokyo').toFormat('yyyy-MM-dd HH:mm:ss');

return { jstTime };

$now とは?
n8nのCodeノード内で使える特別なオブジェクトで、ワークフローが実行された瞬間の日時(LuxonのDateTimeオブジェクト)を持っています。これを使うのが一番確実です。

🛠️ 解決策2:バニラJS(標準機能)で戦う

n8n以外の環境(純粋なNode.jsなど)や、Luxonを使わずに標準の Date オブジェクトだけで解決したい場合は、toLocaleString を使います。

const date = new Date();

// オプションでタイムゾーンを指定する
const jstString = date.toLocaleString('ja-JP', { timeZone: 'Asia/Tokyo' });

return { jstString };

単純に date.setHours(date.getHours() + 9) のように時間を足し算する方法もありますが、うるう秒や将来的な変更に対応できない場合があるため、可能な限りタイムゾーン指定機能を使うことをお勧めします。

💻 実践コード:n8n Codeノード用サンプル

実際にn8nの「Codeノード」に貼り付けて、挙動の違いを確認できるサンプルコードです。

n8n_timezone_test.js
// n8nのCodeノードで実行してください

// 1. そのままのDate (UTCになることが多い)
const rawDate = new Date();

// 2. 手動で9時間足す (非推奨だがよく見るやつ)
const manualDate = new Date(rawDate.getTime() + 9 * 60 * 60 * 1000);

// 3. toLocaleStringを使う (標準JSでの正攻法)
const localeString = rawDate.toLocaleString('ja-JP', { 
  timeZone: 'Asia/Tokyo',
  year: 'numeric',
  month: '2-digit',
  day: '2-digit',
  hour: '2-digit',
  minute: '2-digit',
  second: '2-digit'
});

// 4. n8n組み込みのLuxonを使う (推奨!一番楽)
// $now はn8nが提供するLuxon DateTimeオブジェクトです
const luxonTime = $now.setZone('Asia/Tokyo').toFormat('yyyy-MM-dd HH:mm:ss');

// 5. 昨日の日付を取得したい場合 (Luxonならチェーンメソッドで書ける)
const yesterday = $now.minus({ days: 1 }).setZone('Asia/Tokyo').toFormat('yyyy-MM-dd');

return [
  {
    json: {
      label: "1. UTC (そのまま)",
      value: rawDate.toISOString() // 末尾にZがつくのはUTC
    }
  },
  {
    json: {
      label: "2. 手動計算 (JST)",
      value: manualDate.toISOString().replace('Z', '') // 無理やりJSTの値にしたもの
    }
  },
  {
    json: {
      label: "3. toLocaleString (JST)",
      value: localeString
    }
  },
  {
    json: {
      label: "4. Luxon (JST) ★推奨",
      value: luxonTime
    }
  },
  {
    json: {
      label: "5. 昨日 (Luxon)",
      value: yesterday
    }
  }
];

⚙️ 環境設定:Dockerで動かしている場合

もしあなたがn8nをDocker(セルフホスト)で動かしているなら、環境変数でデフォルトのタイムゾーンを設定してしまうのが手っ取り早いです。

docker-compose.yml に以下を追加します。

environment:
  - GENERIC_TIMEZONE=Asia/Tokyo
  - TZ=Asia/Tokyo

注意点
GENERIC_TIMEZONE を設定しても、Cron(Scheduleノード)の実行時間はJSTになりますが、Codeノード内で new Date() をした際の結果は依然としてUTC(またはコンテナのシステム時刻)になる場合があります。
コード内で日時を扱う際は、やはり 解決策1(Luxon) で明示的にタイムゾーンを指定するのが最も安全です。

まとめ

  • n8nやNode.jsは基本的に UTC(世界標準時) で動いている。
  • 日本時間は UTC + 9時間
  • n8n内なら $now.setZone('Asia/Tokyo') を使うのが最強の解決策。
  • Docker環境なら環境変数 GENERIC_TIMEZONE も忘れずに。

これで「日付がズレててデータが取れない!」という呪いからは解放です🧙‍♂️
良き自動化ライフを!

最後に:業務委託のご相談を承ります

私は業務委託エンジニアとしてWEB制作やシステム開発を請け負っています。最新技術を活用したレスポンシブなWebサイト制作、インタラクティブなアプリケーション開発、API連携など幅広いご要望に対応可能です。

「課題解決に向けた即戦力が欲しい」「高品質なWeb制作を依頼したい」という方は、お気軽にご相談ください。一緒にビジネスの成長を目指しましょう!

👉 ポートフォリオ

🌳 らくらくサイト

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?