EC-CUBE4 Doctrine MySQL PHP

EC-CUBE 4のテーブルにSQLで直接INSERTする時、create_dateupdate_dateにはNOW()ではなくUTC_TIMESTAMP()を使います。EC-CUBEは日時をUTCで保存し、読み出す時にアプリケーションのタイムゾーンへ戻す作りになっているためです。NOW()を使うと、MySQLサーバーのタイムゾーンが日本時間の環境では9時間進んだ値が入ります。

日時はUTCに変換して保存される

app/config/eccube/packages/doctrine.yamlで、Doctrineのdatetimedatetimetz型がEC-CUBE独自の型に差し替えられています。

datetime: 'Eccube\Doctrine\DBAL\Types\UTCDateTimeType'
datetimetz: 'Eccube\Doctrine\DBAL\Types\UTCDateTimeTzType'

この型の保存処理は、渡されたDateTimeのタイムゾーンをUTCに変えてから親クラスの変換に渡しています。

public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
    if ($value instanceof \DateTime) {
        $value->setTimezone(self::getUtcTimeZone());
    }
    return parent::convertToDatabaseValue($value, $platform);
}

つまりエンティティ経由で保存された行は、管理画面で12時13分と表示されていてもDBには03時13分と入っています。SQLで直接INSERTする行も、同じ基準に揃えないと、その行だけ9時間ずれて表示されます。

NOW()は環境によって値が変わる

NOW()はMySQLセッションのtime_zoneに従います。Dockerのローカル環境はUTCで動いていることが多く、そこではNOW()UTC_TIMESTAMP()が同じ値を返すため、ずれに気付きません。本番のRDSやレンタルサーバーがJST設定だと、同じSQLで9時間進んだ値が入ります。

環境に依存しないUTC_TIMESTAMP()を使えば、どのサーバーで流しても同じ結果になります。

INSERT INTO dtb_sample (name, sort_no, create_date, update_date)
VALUES ('見本', 1, UTC_TIMESTAMP(), UTC_TIMESTAMP());

固定の日時を入れる場合

「9月24日の朝9時」のように決まった日本時間を入れたい時は、CONVERT_TZでオフセットを指定して変換します。タイムゾーン名(Asia/Tokyo)を使う書き方はMySQL側にタイムゾーンテーブルが読み込まれていないとNULLになるので、オフセット表記の方が確実です。

CONVERT_TZ('2026-09-24 09:00:00', '+09:00', '+00:00')
-- 結果: 2026-09-24 00:00:00

入った値の確認

INSERT後に該当行をSELECTして、日本時間より9時間前の値になっていれば正常です。管理画面で表示すると日本時間に戻っています。もし管理画面の表示が実際より9時間進んでいたら、その行はNOW()か日本時間の文字列で入れたものです。UPDATE ... SET create_date = CONVERT_TZ(create_date, '+09:00', '+00:00')のように、その行だけ9時間戻せば直ります。

日本発!ECオープンプラットフォーム「EC-CUBE」 EC-CUBEゴールドパートナー EC-CUBEは株式会社イーシーキューブの商標です

EC-CUBEに関するお問い合わせ


    [重要]現在公式にセキュリティサポートが切れていないPHPは8.1以上、MySQLは8.0以上で、対応しているEC-CUBEバージョンは4.2以上です。古いEC-CUBEを使っている方は適切なタイミングでバージョンアップをご検討ください。

    EC-CUBEバージョンアップ