0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

展示会の会期データから「日程が重なる週」を見つける — 区間の重なり判定

0
Posted at

展示会の会期データから「日程が重なる週」を見つける — 区間の重なり判定

イベントの一覧を「開始日順に並べる」だけで済ませていると、同じ日に別の会場で開かれているものが見えません。

会期は点ではなく区間です。区間として持てば、重なりは機械的に出せます。印刷・パッケージ系の展示会カレンダーを題材に、実装と落とし穴を整理します。

PrintBiz

→ 印刷・パッケージの展示会日程を確認するなら PrintBiz

扱うデータ

会期・名称・会場の3つだけあれば足ります。

[
  { "name": "第28回 マーケティングWeek【秋】2026", "start": "2026-10-07", "end": "2026-10-09", "venue": "東京ビッグサイト" },
  { "name": "第30回 ライフスタイルWeek【秋】2026", "start": "2026-10-07", "end": "2026-10-09", "venue": "東京ビッグサイト" },
  { "name": "TOKYO PACK 2026",                      "start": "2026-10-14", "end": "2026-10-16", "venue": "東京ビッグサイト 東展示棟" },
  { "name": "ラベルフォーラムジャパン2026",          "start": "2026-10-14", "end": "2026-10-16", "venue": "東京ビッグサイト 西展示棟3ホール" },
  { "name": "第74回 プレミアム・インセンティブショー秋2026", "start": "2026-10-14", "end": "2026-10-16", "venue": "サンシャインシティ 文化会館ビル" },
  { "name": "第67回 サイン&ディスプレイショウ 2026",  "start": "2026-10-21", "end": "2026-10-23", "venue": "東京ビッグサイト 有明GYM-EX" }
]

end は最終日を含む日付です。ここを半開区間だと思い込むと、翌日開始のイベントを「重なっている」と誤検出します。

重なりの判定

閉区間 [s1, e1] と [s2, e2] が重なる条件は、これだけです。

const overlaps = (a, b) => a.start <= b.end && b.start <= a.end;

「重ならない条件(一方が完全に前)」を否定したものです。場合分けを4通り書きたくなりますが、必要ありません。

日付が YYYY-MM-DD の文字列なら、辞書順比較がそのまま日付順比較になります。Date に変換する必要はなく、タイムゾーンの事故も起きません。この形式を崩さないことが実装上いちばん効きます。

総当たりで組を出す

件数が数十なら総当たりで十分です。

function overlappingPairs(events) {
  const out = [];
  for (let i = 0; i < events.length; i++) {
    for (let j = i + 1; j < events.length; j++) {
      if (overlaps(events[i], events[j])) out.push([events[i], events[j]]);
    }
  }
  return out;
}

上のデータで実行すると、次の組が出ます。

  • マーケティングWeek【秋】 × ライフスタイルWeek【秋】(10/07〜10/09)
  • TOKYO PACK × ラベルフォーラムジャパン(10/14〜10/16)
  • TOKYO PACK × プレミアム・インセンティブショー秋(10/14〜10/16)
  • ラベルフォーラムジャパン × プレミアム・インセンティブショー秋(10/14〜10/16)

サイン&ディスプレイショウ(10/21〜10/23)は誰とも重なりません。10/16 と 10/21 が別区間であることが正しく判定できています。

組ではなく「かたまり」で出す

上の出力は組なので、3つ重なると3行に増えます。読む側が欲しいのはかたまりです。

開始日でソートしてから、区間をマージしていきます。

function clusters(events) {
  const sorted = [...events].sort((a, b) => (a.start < b.start ? -1 : a.start > b.start ? 1 : 0));
  const out = [];
  for (const ev of sorted) {
    const last = out[out.length - 1];
    if (last && ev.start <= last.end) {
      last.items.push(ev);
      if (ev.end > last.end) last.end = ev.end;   // 終了日を伸ばす
    } else {
      out.push({ start: ev.start, end: ev.end, items: [ev] });
    }
  }
  return out.filter((c) => c.items.length > 1);
}

結果はこうなります。

2026-10-07〜2026-10-09  2件
2026-10-14〜2026-10-16  3件

last.end を伸ばす行を忘れると、長い会期が後続を拾えません。 5日間のイベントの2日目に始まる3日間のイベントは、マージ後の終了日を更新しないと取りこぼします。

会場を見て「行けるか」を判定する

重なっていても、同じ会場なら1日で回れます。判定を分けます。

const sameSite = (a, b) => site(a.venue) === site(b.venue);
const site = (v) => v.split(/[  ]/)[0];   // 「東京ビッグサイト 東展示棟」→「東京ビッグサイト」

10/14〜10/16 のかたまりに当てると、TOKYO PACK とラベルフォーラムジャパンはどちらも東京ビッグサイト、プレミアム・インセンティブショー秋はサンシャインシティ。移動が発生するのは1件だけと分かります。

棟名で切っている点が要注意です。東京ビッグサイトの「有明GYM-EX」は展示棟とは別の建物なので、この粗い判定では同一会場に見えます。厳密にやるなら棟の対応表が要ります。ここは用途に応じて割り切るところです。

開催の周期が違うものを混ぜない

展示会カレンダー

同じ配列に、毎年のものと数年に一度のものが混ざります。

IGAS2027 は2027年8月、drupa 2028 は2028年5月、interpack 2029 は2029年6月。重なり判定そのものには影響しませんが、「今後3か月」で切ると常に視界から消えます。

期間で絞る処理を書くときは、周期の長いものを別枠で必ず表示する、といった逃げ道を用意しておくほうが実用的です。

名称変更を吸収する

もうひとつ実データ側の話です。ラベル関連の国際展は Labelexpo から LOUPE に名称が変わっています。

名前をキーにして突き合わせる設計にしていると、改称の年にデータが分断されます。安定した ID を別に振るか、旧称を配列で持つ必要があります。

{ "id": "loupe-americas", "name": "LOUPE Americas 2026", "aliases": ["Labelexpo Americas"] }

手元で確かめる

一覧が生きているかどうかは、curl で見出しの並びを確認すれば足ります。

curl -s https://print-biz.net/ -o /dev/null -w '%{http_code}\n'

業界ニュース

会期・会場は PrintBiz の展示会一覧に載っているものを使いました。2026年9月時点で、終了分を含めて39件が会期順に並んでいます。ニュースは見出しと概要のみで本文は原文へのリンク、コラムは経営系と技術系の2系統という構成でした。

まとめ

  • 会期は閉区間で持ち、a.start <= b.end && b.start <= a.end の1行で判定する
  • 日付は YYYY-MM-DD の文字列のまま比較すると事故が減る
  • 組ではなくマージした「かたまり」で出す。終了日を伸ばす処理を忘れない
  • 会場は正規化しないと「同じ会場」の判定が甘くなる
  • 周期の長いイベントは期間フィルタから漏れる。名称変更は別 ID で吸収する

会期は変更されることがあります。実際に行く判断は主催者の告知で確認してください。

本ページはプロモーションが含まれています

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?