日本語 · English

isOpen / bizOpen / bizClose — 営業時間の標準導出

分類: カレンダー実体の標準導出(ADR-41) / シグネチャ: isOpen(t) : Bool(値述語)・ bizOpen/bizClose : Stream(導出ストリーム) / 名はいずれも確定(2026-07-09・F51 の一括確定。 供給側は opens/closes から sessionOpens/sessionCloses に改名して確定=ADR-41 改訂)。 規範は spec §3.9.1・ADR-41。

意味

在圏 calendar: の実体 C が対の予約公開語 sessionOpenssessionCloses(開場列・閉場列=営業時間の 供給規約。実体 tz の市民座標=壁時計の事実として宣言・任意)を持つとき、言語が一律に規定する:

導出は実体相対——判定材料(どの日が休みか・時刻をどの tz で読むか)は実体の文化で解決され、 読み手の premise に依存しない(bizDay利用側相対の日軸とは役割が違う。 東証が開いているかは東証の文化だけで決まる事実——クロス tz の読み手からも tz 検査に掛からず読める)。 セッションの営業日性は開場日で読む——深夜セッション(開 22:00・閉 翌 03:00)の尾部は開場日に 従う(金曜夜のセッションは土曜 0 時台も営業中・日曜夜のセッションは丸ごと休み)。

単一セッション 9:00–15:00・半日休(1/6 は 11:30 引け)・祝日 1/1。「営業時間内の毎正時」は isOpen 一語(../design/40-examples/06-business-hours.md §6.3 の帯+証人パターンの手組みがこの一語に縮む):

# eval: 2026-01-05..2026-01-08
premise TSE {
  calendar-system: Gregorian
  tz: "Asia/Tokyo"
  source: "example"
  satSunC = everyDay |> filter(d => weekday(d) == Sat or weekday(d) == Sun)
  holidays = [2026-01-01] covering: 2026..2026
  nonWorking = satSunC | holidays
  nine  = chronos grid 1d anchor: 2026-01-01T09:00
  three = chronos grid 1d anchor: 2026-01-01T15:00
  halfDayCloses = [2026-01-06T11:30] covering: 2026..2026
  sessionOpens  = nine |> first
  sessionCloses = (three |> first |> filter(t => not coincides(halfDayCloses, day, t))) | halfDayCloses
}
premise JP2 {
  calendar-system: Gregorian
  calendar: TSE
  tz: "Asia/Tokyo"
  wkst: Mon
  hourly = everyInstant |> strideBy(1h, from: 2026-01-01)
}
@JP2
hourly |> filter(t => isOpen(t))
#=> 2026-01-05T09:00 2026-01-05T10:00 2026-01-05T11:00 2026-01-05T12:00 2026-01-05T13:00 2026-01-05T14:00
#=> 2026-01-06T09:00 2026-01-06T10:00 2026-01-06T11:00
#=> 2026-01-07T09:00 2026-01-07T10:00 2026-01-07T11:00 2026-01-07T12:00 2026-01-07T13:00 2026-01-07T14:00

「毎営業日の開場に発火」= bizOpen そのもの(ADR-38 改訂後の正準形——1/1 祝・1/3-1/4 土日は落ちる):

# eval: 2026-01-01..2026-01-08
premise TSE {
  calendar-system: Gregorian
  tz: "Asia/Tokyo"
  source: "example"
  satSunC = everyDay |> filter(d => weekday(d) == Sat or weekday(d) == Sun)
  holidays = [2026-01-01] covering: 2026..2026
  nonWorking = satSunC | holidays
  nine  = chronos grid 1d anchor: 2026-01-01T09:00
  three = chronos grid 1d anchor: 2026-01-01T15:00
  sessionOpens  = nine |> first
  sessionCloses = three |> first
}
premise JP2 { calendar-system: Gregorian; calendar: TSE; tz: "Asia/Tokyo"; wkst: Mon }
@JP2
bizOpen
#=> 2026-01-02T09:00 2026-01-05T09:00 2026-01-06T09:00 2026-01-07T09:00

落とし穴

関連

nonWorking(実体・bizDay=利用側相対の日軸)・coincides (窓所属の述語——isOpen は同族の導出形)・grid(時刻付き anchor=壁時計 tick・ ADR-31 改訂 2)・strideByshift(経過保存——壁時計はこちらでなく 宣言側の領分)・spec §3.9.1・ADR-41/ADR-31 改訂 2・F67/F79/F85/F89。