解説
AIに日別集計を頼む前に:UTCと日本時間の日付境界をそろえよう
同じ6件の日時でも、UTCと日本時間では日別件数が変わる。変換してから日付を取り出す順番、翌日0時を含めない範囲、確認用IDを付けた依頼文を整理する。

AIへ日時の一覧を渡し、「27日の件数を数えて」と頼んだ。同じ元データなのに、確認した集計と数が違う。日付の文字だけを切り出し、タイムゾーンの変換を飛ばしていないか確認しよう。
この記事では架空の6件を使い、同じ瞬間をUTCと日本時間でどう数えるか比べる。実際の顧客データやログインは不要。AIの回答を実測した記事ではなく、依頼条件と正解を照合する練習だよ。
「27日」がどの地域の日付かを決める
UTCは時刻の基準、日本時間はUTCより9時間進んだ時刻。ISO形式の日時では、末尾のZがUTCを、+09:00がUTCから9時間進んだオフセットを表す。
2026-10-26T15:00:00Zは、日本時間では2026-10-27の0時。同じ瞬間でも、日付だけを見ると26日と27日に分かれるよ。日本時間の日別集計なら、先に日時を日本時間へ変換してから、日付を取り出す必要がある。
| ID | 元の日時 | 日本時間へ変換した日時 |
|---|---|---|
| A | 2026-10-26T14:59:59Z | 10月26日23:59:59 |
| B | 2026-10-26T15:00:00Z | 10月27日00:00:00 |
| C | 2026-10-26T23:30:00Z | 10月27日08:30:00 |
| D | 2026-10-27T09:00:00+09:00 | 10月27日09:00:00 |
| E | 2026-10-27T23:59:59+09:00 | 10月27日23:59:59 |
| F | 2026-10-28T00:00:00+09:00 | 10月28日00:00:00 |
Dのように最初から日本時間の日時へ、さらに9時間を足すと誤りになる。元のオフセットを含めて日時として解釈し、対象のタイムゾーンへ変換しよう。
日本時間の27日は、B・C・D・Eの4件
今回は各IDが別のイベントを1件表す。ユーザー数や重複排除後の件数を数える例ではないよ。
日本時間でまとめると、26日は1件、27日は4件、28日は1件。UTCへそろえてから日付を取ると、26日が3件、27日が3件になる。片方が必ず間違いなのではなく、集計の基準が違うんだ。
集計表の見出しにも「日付(日本時間)」のように基準を添えたい。同じデータから作った表でも、基準を書かずに並べると、増減があったように読み違えてしまう。
翌日の0時を両方の日へ入れない
日本時間の27日を範囲で示すなら、27日0時以上、28日0時未満とする。開始を含み、終了を含めない区切りだよ。
UTCの値で表すと、2026-10-26T15:00:00Z以上、2026-10-27T15:00:00Z未満。Fはちょうど終了境界なので、27日の4件には含めない。
23時59分59秒まで、とだけ書くと、小数秒のあるデータで意図が曖昧になることがある。日時の精度を決め、次の日の開始より前、という条件で示すと境界を確かめやすい。
AIへの依頼には、変換後の表と確認用IDも求める
以下は、今回の架空データに対する依頼文の例。
各IDは別イベント1件です。日時のZと+09:00を解釈し、
すべて日本時間(UTC+09:00)へ変換してから日別に数えてください。
元日時の先頭10文字でグループ化しないでください。
出力は「ID・元日時・日本時間の日時」と「日付・件数・対象ID」。
27日は27日0時以上、28日0時未満です。
オフセットのない日時は推測で処理せず、確認が必要として分けてください。
日別の合計だけでなく対象IDを出すと、どの行が別の日へ入ったかをたどれる。ただし、AIが付けた内訳も自動的に正しいとは限らない。元データと境界条件で照合しよう。
OpenAIの公式ガイドは、明確な指示や例を用いた依頼の組み立てを説明している。ここに載せた依頼文や正解の6件は編集部が作ったもので、特定モデルが必ず正しく数えると確認したものではないよ。
Pythonで独立して確認する小さな例
次はPython 3.12で確認した例。日時のオフセットを保持したまま読み、日本時間へ変換する。
from collections import Counter
from datetime import datetime, timezone, timedelta
jst = timezone(timedelta(hours=9))
rows = [
("A", "2026-10-26T14:59:59Z"),
("B", "2026-10-26T15:00:00Z"),
("C", "2026-10-26T23:30:00Z"),
("D", "2026-10-27T09:00:00+09:00"),
("E", "2026-10-27T23:59:59+09:00"),
("F", "2026-10-28T00:00:00+09:00"),
]
counts = Counter()
for event_id, value in rows:
moment = datetime.fromisoformat(value.replace("Z", "+00:00"))
if moment.utcoffset() is None:
raise ValueError("タイムゾーンの確認が必要")
local = moment.astimezone(jst)
print(event_id, local.isoformat())
counts[local.date().isoformat()] += 1
print(dict(sorted(counts.items())))
期待する日別件数は、2026-10-26が1、2026-10-27が4、2026-10-28が1。編集部では変換結果、UTCでの3件・3件、開始・終了の境界も別途照合した。任意の地域の夏時間まで、この固定+09:00の例で扱えるという意味ではないよ。
日時の表記の読み方はUTCと日本時間の基礎、日付の含め方の問題は期間の開始日・終了日も参照してね。

みんなのコメント 0
感想や、試してみたことを聞かせてね。コメント・返信は承認後に公開されます。
最初のコメントをどうぞ。