時間意味と境界取得の設計整理¶
背景¶
現状は water_info と JMA の時間データについて、取得元が持つ時刻の意味と、内部で保持している時刻の意味が一部一致していない。
特に以下が問題になる。
water_infoのS/Rを本来は瞬間値として扱いたいが、現実装では 1 時間戻した区間値のように保存している。UやJMAの雨量は区間値として扱う前提があるが、境界時刻の構築のために前後のデータ取得範囲を明示できていない。request_windowとfetch_windowとpublish_windowが分離されておらず、境界を埋めるための余分取得と最終出力範囲の切り戻しが設計として固定されていない。
この資料では、時間意味と取得境界のルールを統一し、後続実装の判断を不要にすることを目的とする。
用語定義¶
request_window- ユーザーが欲しい論理期間
- 例:
2025-01-01 00:00:00から2025-01-04 00:00:00の排他的上限 fetch_window- 境界レコードを構築するために、実際に取得する期間
request_windowより広くなることがあるpublish_window- 正規化後に CSV / Excel / Parquet / グラフへ最終反映する期間
- 原則として
request_windowと一致させる observed_at- 時系列上でレコードを代表させる時刻
period_start_at- 区間値の開始時刻
period_end_at- 区間値の終了時刻
value_semantics- 値の意味
instantaneousまたはinterval
正式ルール¶
1. 指標ごとの時間意味¶
water_info¶
S水位value_semantics = instantaneousR流量value_semantics = instantaneousU雨量value_semantics = interval
JMA¶
hourly/10min/dailyの降水量value_semantics = interval
2. unified schema の意味¶
瞬間値¶
observed_at- 実観測時刻そのもの
period_start_atNULLperiod_end_atNULL
適用対象:
water_info:Swater_info:R
区間値¶
observed_at- 区間終端時刻
period_start_at- 区間開始時刻
period_end_at- 区間終了時刻
適用対象:
water_info:UJMA rainfall
3. publish_window での切り方¶
- 瞬間値
publish_window判定はobserved_atに対して行う- 判定式は
request_start <= observed_at <= request_end_exclusive - 区間値
publish_window判定はperiod_end_atに対して行う- 判定式は
request_start <= period_end_at <= request_end_exclusive
理由:
- 瞬間値は観測時刻そのものが主キーであるため
- 区間値は終端時刻で時系列整列する方針とするため
境界取得ルール¶
基本方針¶
出力側で不足が起きないよう、常に以下の順で処理する。
request_windowを受け取るvalue_semanticsとintervalに応じてfetch_windowを拡張する- 取得元データを正規化する
- unified records を作る
publish_windowで切り戻す- CSV / Excel / Parquet / グラフへ反映する
fetch_window 拡張ルール¶
water_info:S / R¶
- 瞬間値
- 取得元時刻に
24:00相当表現が混ざりうるため、request_windowの先頭を正しく作るには 1 ステップ前が必要 hourlyの場合:fetch_window.start = request_window.start - 1 hourfetch_window.end = request_window.enddailyの場合:fetch_window.start = request_window.start - 1 dayfetch_window.end = request_window.end
water_info:U¶
- 区間値
- request の先頭区間を作るには、終端側レコードが必要
hourlyの場合:fetch_window.start = request_window.startfetch_window.end = request_window.end- ただし取得元の表記都合で先頭
00:00を前日24:00として持つ場合は 1 ステップ前を追加取得する dailyの場合:fetch_window.start = request_window.startfetch_window.end = request_window.end- 同様に取得元の終端表記都合がある場合は 1 日前を追加取得する
JMA rainfall¶
- すべて区間値
- 利用者向けの終了指定は「当日末尾」ではなく
request_end_exclusiveとして扱う - 例:
2026-03-03指定は内部的に2026-03-04 00:00:00を意味する hourlyfetch_window.start = request_window.start - 1 hourfetch_window.end = request_window.end10minfetch_window.start = request_window.start - 10 minfetch_window.end = request_window.enddailyfetch_window.start = request_window.startfetch_window.end = request_window.end
補足:
- 旧来の
24時/23:59:59.999999吸収はfetch_windowと正規化の責務として扱う - 出力時に補正しない
現状実装からの修正点¶
water_info¶
S/Rは区間化をやめるobserved_atを取得元時刻として保持するperiod_start_at/period_end_atはNULLにする- Excel の時間列は
period_end_atではなくobserved_atを主に使う - request 範囲先頭の瞬間値を作るため、1 ステップ前の取得を導入する
water_info:U¶
intervalごとの区間値として統一する- 区間は
period_start_at/period_end_atで保持する observed_at = period_end_atとする- 先頭区間が欠けないように、必要な場合は 1 ステップ前を追加取得する
JMA¶
hourly/10min/dailyを区間値として扱うobserved_at = period_end_atを維持する24時や23:59:59.999999の吸収は正規化段階に限定するCSVのhour=24のような表示残りは排除し、最終的に実時刻へ寄せる10minのperiod_start_at=...59.999999のような疑似境界を排除する- 先頭の
0:00終端区間も保持する request_endの実装で23:59:59.999999を生成しない
影響範囲¶
直接影響¶
src/water_info/service/flow_fetch.pysrc/water_info/infra/dataframe_utils.pysrc/water_info/entry.pysrc/water_info/service/flow_write.pysrc/water_info/cli.pysrc/jma_rainfall_pipeline/controller/weather_data_controller.pysrc/jma_rainfall_pipeline/exporter/csv_exporter.pysrc/jma_rainfall_pipeline/exporter/parquet_exporter.pysrc/hydrology_graphs/io/parquet_store.py
間接影響¶
hydrology_graphsの時系列解釈river_metaの共通フォーマット化ロジック- 既存 Parquet の互換方針
- CSV / Excel のヘッダー説明とドキュメント
実装方針¶
Phase 1: スキーマ定義の修正¶
value_semanticsを内部設計に追加するobserved_at/period_start_at/period_end_atの意味を正式固定するS/R/U/JMAの対応表をコードコメントではなく設計として残す
Phase 2: 取得窓の分離¶
request_window/fetch_window/publish_windowを明示的に導入する- 取得元ごとに
fetch_window拡張関数を実装する - 実データ取得前に拡張済み window を計算する
Phase 3: 正規化の修正¶
water_info:S/Rを瞬間値として正規化するwater_info:Uを区間値として正規化するJMA hourly/10minの境界計算を実時間ベースに置換する
Phase 4: 出力の修正¶
- CSV / Excel / Parquet で同じ時間意味を使う
- Excel 時刻列を
value_semanticsに応じて切り替える - CLI 出力要約も
observed_at中心へ揃える
Phase 5: 後段利用の修正¶
hydrology_graphsが瞬間値と区間値を区別できるようにする- 必要なら描画側で
value_semanticsを見て補助処理を分ける
テスト項目¶
water_info:S / R¶
- 先頭
00:00を request したとき、前日追加取得によりobserved_at=00:00が構築できる period_start_at/period_end_atがNULLで保存される- Excel / CSV / Parquet が同じ時刻意味になる
water_info:U¶
- 先頭区間が欠けない
observed_at = period_end_atperiod_start_at/period_end_atが interval に一致する
JMA¶
hourlyでhour=24が残らない10minで59.999999境界が残らないpublish_windowで切り戻した結果が request 範囲に一致する
共通¶
- 月跨ぎ
- 年跨ぎ
- request 先頭・末尾の境界
- 欠測を含むケース
- 旧 Parquet との差分確認
判断済み事項¶
water_info:S/Rは瞬間値とするwater_info:Uは区間値とするJMA rainfallは区間値とする- 出力切り戻しは
publish_windowで行う - 境界を埋めるための余分取得は
fetch_windowの責務とする
保留事項¶
- 既存 Parquet を再生成するか、互換差分として併存させるか
value_semanticsを Parquet の列として明示追加するか、metric/source/interval から導出するかwater_info daily:S/Rの取得元時刻が厳密に瞬間値とみなせるかの最終確認