【要約】「1日2件」の上限チェックが常に0件と誤判定していた——SQLiteのタイムゾーン二重変換バグ [Zenn_Python] | Summary by TechDistill
> Source: Zenn_Python
Execute Primary Source
// Problem
開発者がClaude CodeによるSNS自動投稿のスパム回避策として、1日あたりの投稿上限を管理する仕組みを導入した際、上限チェックが機能しない問題に直面した。具体的には、以下の技術的課題が発生していた。
- ・SQLiteの
datetime()関数が、オフセットなしの文字列をUTCとみなして処理する。 - ・JSTで保存された
posted_atにさらに+9 hoursを加算するため、日付が翌日に繰り上がる。 - ・15時以降の投稿が「翌日」と判定され、当日のカウントが0件となる。
- ・設計ミスが複数のタスクファイルに複製されていた。
// Approach
開発者は、時刻演算による非対称な挙動を回避するため、以下の手法で問題に対処した。
- ・暫定策として、日付演算を廃止し、
posted_at LIKE '2026-08-14%'による文字列の前方一致を用いた集計に変更した。 - ・恒久策として、新規書き込み時にオフセット付きのISO8601形式で保存するよう、データモデルの統一を進めている。
// Result
開発者は、暫定的な回避策の導入により、時刻計算の不整合を回避し、正しい投稿件数の集計を実現した。
- ・
LIKE演算子の利用により、タイムゾーンの解釈問題に依存しない集計が可能となった。 - ・根本原因である「オフセットなしのローカル時刻保存」の修正に向けた、データ形式の統一タスクが開始された。
Senior Engineer Insight
> 時刻管理は、分散システムにおいて最も脆弱な箇所の一つである。SQLiteのように「オフセットなし=UTC」と暗黙的に扱うエンジンでは、データの保存形式とクエリの前提が一致しているかを厳格に検証せねばならない。本件のように、ロジックの正当性だけでなく、実データと返り値を突き合わせる検証が不可欠である。設計段階で、時刻は常にUTCで統一し、オフセットを明示する原則を徹底すべきだ。