個人family-trips

家族旅行アーカイブサイト family-trips(Astro + Cloudflare Pages)で、旅行詳細ページのガントカレンダーを見ていたら、8/28 の最終便が右端で枠の外に半分はみ出していた。

正確には、自分が気づいたのではなくユーザーから指摘が飛んできた。

8月28日のところなんか見切れてるんで、カレンダーもっと縦に見切れないようにしてもらえますか。バッファを1日ぐらい取ってていいんで

pnpm dev でローカルを 4321 番ポートに立ち上げて該当ページを開くと、確かに「大分→羽田 (6J096) 16:50-18:35」のバーが右端の枠線にぶつかって、後半が切れていた。

何が起きていたか

該当ファイルは src/pages/trips/[...slug].astro 一本。ガント描画の endDate を、コンテンツの終了日(8/28)ジャストで渡していた。

  • 8/28 の枠は 0:00 から 23:59 までの 1 日分しか確保されていない
  • 8/28 18:35 着の便のバーは 18:35 まで伸びる
  • 右端のラベル領域・余白に侵食して、視覚的に「見切れている」状態になっていた

コンテンツデータ的には正しい(旅行は 8/28 で終わる)が、描画上は1日のれんが足りない、というだけの話だった。

どう直したか

ここで一瞬迷ったのは、「コンテンツ側の endDate を 8/29 にずらして済ませる」案だった。

これをやると、旅行アーカイブのメタデータが現実と1日ずれる。旅行一覧の集計や日付ラベルに影響が出るのが嫌だったので、却下した。

採用したのは、コンテンツの正データは触らず、描画側にだけ 1 日のれんを足す方針。

具体的には、ガント描画関数に渡す終点を ganttEndDate = endDate + 1日 のダミーに差し替えるだけ。

// src/pages/trips/[...slug].astro 内
// コンテンツの endDate は壊さない。表示専用の終点を 1 日後ろにずらす
const ganttEndDate = new Date(endDate)
ganttEndDate.setDate(ganttEndDate.getDate() + 1)

const days = buildDays(startDate, ganttEndDate)
const bars = buildBars(events, startDate, ganttEndDate)

これで buildDaysbuildBars の表示範囲が 1 日広がる。コンテンツのフロントマター側の endDate: 2026-08-28 はそのまま据え置き。

結果

ブラウザをリロードしたら、

  • 8/28 の最終便「大分→羽田 (6J096) 16:50-18:35」のバーが、右側の余白に収まって、最後まで読める状態になった
  • 8/29(土) のバッファ行が下に追加されて、何も予定がない空行として描画されている
  • 旅行一覧側の表示・日付ラベル・集計は何も変わっていない(コンテンツの endDate を触っていないので当然)

振り返り

判断としては「データの正しさ表示の見やすさは別レイヤーで解決する」が正解だった。

データ側を1日ずらすのは一見最小修正に見えるが、後で集計や URL を組むときに「なぜ実日付と1日ずれているのか」を毎回思い出す羽目になる。今回みたいに表示の都合は表示レイヤーで吸収しておく方が、半年後の自分が事故らない。

修正は Claude Code に「ganttEndDate を別に作って +1 日して、描画関数2つにだけ渡し替えて」と一行で頼んで、差分は数行で終わった。気づきさえあれば直る種類のバグ。