at — 日集合への壁時計時刻の付与
分類: 糖衣(stdlib・Gregorian 公開語=変換) / シグネチャ: at(a) : Stream -> Stream(a は単独時刻リテラル Thh:mm) / 名は確定(ADR-51)
意味
日集合の各日について、その日の壁時計 a 時の時点を返す。展開は壁時計正準形の機械的差し込み
(糖衣=spec §4.8):
at(a) = s => (everyInstant |> strideBy(1d, from: a)) |> filter(t => coincides(s, day, t))
「その日の H 時」は壁時計の概念である。窓単位 shift(unit: hour)は経過時間
意味論(F76)で、DST のある tz では切替日に壁時計からずれる——at は tick(市民日幅の等差=壁時計
保存)で刻むため、切替日でも壁時計を保つ。単独時刻リテラルは epoch 錨日 1970-01-01(在圏 tz)で
錨打ちされる——評価範囲がどこまで過去でも欠けない(ADR-51)。
例
月末営業日の 17:00(経過算術形 snapTo(day) |> shift(+17, unit: hour) の置き換え——JST では
外延同値・警告の経路が消える):
# eval: 2026-08-01..2026-11-01
@JP
bizDay |> within(month) |> last |> at(T17:00)
#=> 2026-08-31T17:00 2026-09-30T17:00 2026-10-30T17:00
10 月は 10/31 が土曜なので前営業日 10/30 の 17:00。DST のある tz では壁時計の保存が経過形との 差になる(NY の春の切替日——経過形なら 10:00 に着地する。06 §6.1):
# eval: 2026-03-07..2026-03-10 tz: America/New_York
premise NY { calendar-system: Gregorian; tz: "America/New_York"; wkst: Sun }
@NY
everyDay |> at(T09:00)
#=> 2026-03-07T09:00 2026-03-08T09:00 2026-03-09T09:00
sub-hour も同様(T07:30——壁時計オフセット保存・F81)。「前日の 23:00」は日の調整を日の層で
済ませてから時刻を貼る: marks |> shift(-1, unit: day) |> at(T23:00)。
落とし穴
atに渡すのは単独時刻リテラル——他は誘導つき静的エラー(ADR-51 追記)。日時リテラル (at(2026-01-01T17:00))や裸の日付リテラルは tick の起点が前方専用のため anchor より前の 日が黙って空になる形で、検査が塞ぐ(ADR-51 が案 B を不採とした理由の防御)。時刻だけを書けば 欠落は構造的に起きない。- 窓付き入力は取らない——誘導つき静的エラー(ADR-51 追記)。展開形は入力を述語として読み直す
ため窓を引き継がず、「毎月の最初の 3 日の朝 7 時」のつもりが通し数えに化ける形だった。正道は
窓は at の後で切る:
everyDay |> at(T07:00) |> within(month) |> first(外延同値)。 - 入力に覆域外の点が残ったまま届くと、その点は
at段で落ちる(還流第 15 便 (e))。展開の 内部filterが覆域外の日に立つ範囲外シグナルを「落として註釈」するため(ADR-37 判断 6 の規約 どおり——糖衣は展開先の意味を継承する)。経過算術形は点を保存して註釈だけ付けるので、覆域を 跨ぐ評価窓では乗り換え前後で点列が変わり得る(例:bizDay |> at(T07:00)を覆域が切れる年末 年始で評価すると覆域外の日の分が出ない——註釈は旧形と同一なので点の増減は註釈から読めない)。 覆域の内側で計算が閉じる評価では一致する。運用の防御は覆域の更新(残走路警告=ADR-37 判断 8) であって式形ではない。結合子を通した後段のatも同じ規則(還流第 20 便 §3・2026-09-03):|・&・\は両辺の註釈を和で輸送する(ADR-37 判断 4)ので、各項の実効被覆域の共通部分の外 =註釈区間に落ちた点がat段で落ちる。単項では 1 点も落ちない(satSun |> at(…)は覆域無限) のに、(satSun | holidays2026) |> at(…)にすると覆域が祝日表の年に縮み、翌年の点が全て消える ——エラーにも警告にもならず、範囲外の註釈だけが残る(点の脱落は註釈から読めない)。 参照されない external は解決されず覆域に関与しない。 atの出力を数える段・segmentByのマーカーに使うと、有限入力でも「無限」側に分類される (還流第 15 便 (b))。展開の tick 由来の endless が filter を素通りするため(保守近似としては 規約どおり)——takeLastでは実装地平線ガードの警告が偽陽性で立ち、segmentBy(labels:)では データラベル不適格の静的エラーになる。正道はどちらも数える段・マーカーは日の層で作り、時刻 付与は後(下の takeLast 項と同じ順序)。- 経過算術形からの乗り換えで消える警告は末尾形の分。マーカー準備側(外部 instants の
snapTo(day))の horizon-clip(端の数点・無害)は残る(ADR-37 判断 8 の既知動作)。 - DST の隙間日(その壁時計時刻が存在しない日)は F81 の規約——隙間明けの最初の瞬間へ 繰り下げ・重複日は最初の出現(09-dst §9.2。「名指しは厳格・導出は規約」——入力リテラルの 明示エラー〈ADR-33〉とは層が違う)。
takeLastと組むときは数える段は日の層・時刻付与は後 (takeLast(3, until: …) |> at(T07:00))——日付リテラルの until: は 00:00 錨なので、時刻付与を 先にすると当日分が数えから外れる。- 単独時刻リテラルは
strideBy(1d, from:)の位置でのみ時点に具現する——他の点位置・他の幅は 誘導つき静的エラー(黙って epoch 日に固定しない。ADR-51)。
関連
strideBy(展開の tick)・coincides(展開の述語)・
takeLast(直近 N との標準合成)・isOpen(時刻の帯は別の器=
営業時間)・ADR-51・F76/F81。