システム開発では、データベースに保存された日時情報を正確に比較することが求められます。
しかし、開発環境と本番環境でタイムゾーンの設定が異なる場合や、日時のミリ秒が影響して意図しない比較結果が得られることがあります。
本記事では、SQLとアプリケーション側の日時処理について詳しく解説し、正確な比較を行う方法を紹介します。
目次
日時比較で発生する問題
データベースに保存された日時と、アプリケーション側から送信された日時を比較する際に、以下のような問題が発生することがあります。
- ミリ秒の影響
- タイムゾーンの違い
- データのフォーマットの違い
SQLでミリ秒を無視して比較する方法
PostgreSQLなどのデータベースでは、DATE_TRUNC 関数を利用することで、ミリ秒以下の情報を切り捨てて比較できます。
SELECT COUNT(*) AS count
FROM テーブル名
WHERE id = $1
AND DATE_TRUNC('second', update_dt) = DATE_TRUNC('second', TO_TIMESTAMP($2, 'YYYY/MM/DD HH24:MI:SS') AT TIME ZONE 'UTC');
SQLのポイント
DATE_TRUNC('second', update_dt)でミリ秒を切り捨てTO_TIMESTAMP($2, 'YYYY/MM/DD HH24:MI:SS')で文字列を日時型に変換AT TIME ZONE 'UTC'でUTC基準に統一
注意点
update_dtがTIMESTAMPTZ型(タイムゾーン付き)かどうかで結果が変わる- アプリケーション側で送信する日時のフォーマットと一致しているか確認が必要
アプリケーション側(JavaScript)のタイムゾーン変換
Node.jsでの日時の処理には luxon ライブラリを使用することが多いです。DateTime を適切に変換する例を紹介します。
import { DateTime } from 'luxon';
const update_dt = '2025-05-14 10:56:46';
const utcDateTime = DateTime.fromISO(update_dt, { zone: 'utc' }).toFormat("yyyy/MM/dd HH:mm:ss");
console.log(utcDateTime); // 2025/05/14 10:56:46
コードのポイント
fromISO(update_dt, { zone: 'utc' })でUTCとして解釈toFormat("yyyy/MM/dd HH:mm:ss")でミリ秒を含まない形式に整形
JSTに変換したい場合
const jstDateTime = DateTime.fromISO(update_dt, { zone: 'utc' }).setZone('Asia/Tokyo').toFormat("yyyy/MM/dd HH:mm:ssZ");
console.log(jstDateTime); // 2025/05/14 10:56:46+09
このコードでは setZone('Asia/Tokyo') を使用して JST(UTC+9)に変換しています。
正確な比較のためのポイントまとめ
- データベース内の時刻のフォーマットとタイムゾーンを確認
- ミリ秒を無視するには
DATE_TRUNC('second', update_dt)を使う - アプリケーション側で送るデータのフォーマットを統一する
- アプリケーションでタイムゾーンを明示的に変換する
まとめ
データベースとアプリケーションでの日時の比較は、ミリ秒やタイムゾーンの違いによって不具合が発生しやすいポイントです。
SQLの DATE_TRUNC を活用し、アプリケーション側では luxon などのライブラリを適切に使うことで、精度の高い比較が可能になります。
開発の際は、常に日時のフォーマットとタイムゾーンを意識し、データが意図した形で処理されているかを検証することが重要です。


コメント