Shopify Functionを触っていると、JavaScriptの標準関数であるnew Date()やDate.now()が、なぜかすべて「1970-01-01 00:00:00 UTC」(エポックタイムの開始時点)を返す現象に遭遇した。最初は環境設定ミスかと思ったが、これはShopify Functionの実行環境が持つサンドボックス制約が原因だったという話だ。
この問題、特にサーバー側の時間情報を利用したい場合に致命的で、そのままではビジネスロジックが成立しない。
何が起きたか(課題)
Shopify Functionの実行環境(WebAssemblyベースのサンドボックス)では、ホストOSの時刻情報に直接アクセスできないため、標準の時刻取得メソッドが常に固定値を返す。
-
new Date()を実行すると、常に1970年1月1日を指す。 -
Date.now()も同様に0を返す。 - この結果、特定の時刻に基づくロジック(例:本日付で割引を適用する、有効期限をチェックする)が正しく機能しない。
どう解決したか(概要)
確実な解決策は、Shopify側が提供しているAPI経由でローカル時刻を取得することだ。Shopify Functionsは、インプットとしてGraphQLのデータを要求できる設計になっている。この機能を利用し、Shopのタイムゾーンに合わせた現在時刻を取得した。
具体的には、Functionのインプット定義(Input型)に、shopオブジェクト内のlocalTimeフィールドを含めるよう設定した。このフィールドはdate型として、ローカルの日付と時刻の情報を含んでいる。
import { Input } from './generated/api';
export function run(input: Input) {
// インプットから直接ローカル時刻の文字列を取得
const shopDateString = input.shop.localTime.date;
// 安全な日付オブジェクトに変換
const safeDate = new Date(shopDateString);
console.log(safeDate);
}
このアプローチにより、サンドボックスの制約を回避し、ストアが設定している正しい現在時刻(ISO 8601形式の文字列)をJavaScriptのDateオブジェクトとして安全に扱えるようになる。
効果(Before/After)
| 項目 | Before(問題発生時) | After(GraphQL利用後) |
|---|---|---|
new Date()の結果 |
1970-01-01T00:00:00.000Z (固定値) | 実行時のストアローカル時刻(例: 2024-10-27T14:30:00+09:00) |
| ロジックの堅牢性 | 低い(時間依存ロジックが機能しない) | 高い(正しい時刻で判定可能) |
この変更で、時間依存のロジックが意図通りに動作するようになり、Functionsの信頼性が大幅に向上した。
🚀 詳細な設定とコードはこちら
具体的なWAFのルール設定や、より詳細なログ解析データは元のブログで公開しています。
👉 Shopify Functionでnew Date()が1970年を返す謎!安全に現在時刻を取得するGraphQLテクニック