← 記事一覧に戻る
テクノロジー

日時バグを実装で潰す5つのチェック

日時バグを実装で潰す5つのチェック

日時バグはなぜ後工程でしか気づかれないのか

日時処理のバグは、開発環境ではまず再現しない。テストを実行する時刻がたまたま日本時間の日中で、DST境界も月末もうるう年も踏まないからだ。結果として「本番で、特定の日にだけ」不具合が起きる。これは偶然ではなく、実装時にチェックすべき項目をリスト化していないことが原因である。シフトレフトの発想で言えば、日時バグは実装フェーズで構造的に潰すのがもっとも費用対効果が高い。

実装時にチェックすべき5つのパターン

1. UTC変換漏れ

ユーザーの入力時刻をそのままサーバーのローカルタイムとして保存し、別のタイムゾーンのユーザーに表示すると時刻がずれる。保存は常にUTC、表示のみユーザーのタイムゾーンで変換する原則を徹底する。

# NG: ローカルタイムのまま保存
Time.now

# OK: UTC で保存し、表示時に変換
Time.now.utc
user_time_zone.at(record.created_at)

2. DST境界

サマータイムを採用する地域では、年に2回、1時間が存在しない、または重複する瞬間がある。「24時間後」を単純な秒数加算で計算すると、DST切り替え日をまたいだときに表示上1時間ずれる。日時の加算はタイムゾーン付きのライブラリ関数に任せ、秒数の直接加算は避ける。

3. 月末日

1月31日に「1ヶ月後」を加算すると、2月には31日が存在しない。使用しているライブラリが3月3日に繰り上げるのか、2月末日にクランプするのかは実装前に必ず確認し、仕様として明記する。契約更新日や請求日の計算で特に踏みやすい。

4. うるう年

2月29日を含む期間計算、年齢計算、サブスクリプションの更新日計算はうるう年で崩れやすい。閏年判定を自前で書かず、標準ライブラリの日付計算に任せる。

5. フォーマット文字列の地域差

「03/04/2026」は米国式ではMarch 4、日本式では4月3日と解釈が割れる。日付を文字列でやり取りする箇所は必ずISO 8601(YYYY-MM-DD)に統一し、表示だけをロケールごとにフォーマットする。APIレスポンスやログに地域依存の書式を混ぜないことが最重要のルールになる。

テストすべき具体的な日付

  • うるう年: 2028-02-29
  • DST開始(春・米国): 2027-03-14
  • DST終了(秋・米国): 2026-11-01
  • 月末+1ヶ月: 2026-01-31 に1ヶ月加算し、2026-02-28になるか確認
  • 日付境界のタイムゾーン差: UTC+14(キリバス)とUTC-12では、同じ瞬間でも暦日が丸1日ずれる

これらの日付をテストデータやE2Eシナリオに固定値として組み込んでおけば、本番を待たずに実装時点で気づける。

Bugoon での実践

日時バグは、報告を受けてから再現するまでの手間が特に大きい。「いつ」の情報が曖昧だと、開発側はどのタイムゾーン・どの瞬間の話をしているのか特定できない。Bugoonのウィジェットはスクリーンショットと操作ステップの記録をその場で残し、そのままGitHub Issueとして起票できるため、再現に必要な文脈を報告時点で漏らさず残せる。起票されたIssueはMCPサーバー経由でClaude CodeやCursorから直接参照できるので、上記のチェックリストを踏まえた修正にそのまま着手しやすい。

レポート送信時刻をタイムゾーン付きで自動的に記録できると、日時起因のバグかどうかの切り分けがさらにしやすくなりそうだが、これは今のところアイデア段階であり、実装されているものではない。

チームのバグ報告を、もっとスムーズに。

Bugoon は無料で始められます。サイトにタグを 1 行追加するだけで、QA と開発の往復がなくなります。

無料で始める