1. 「あと何日」の答えは 3 つある
月曜の午後 2 時。締め切りは来週水曜(11 月 4 日)の 17 時。「あと何日使えるか」と聞かれて、暦を数えれば 9 日、営業日を数えれば 6 日——間に 11 月 3 日(文化の日)が挟まる——、「使える時間」なら今日の残りと当日の 17 時までを足して 51 時間、と答えが 3 つある。
Excel なら NETWORKDAYS に祝日表を渡せば営業日は数えられる。Kairos には「残り日数を返す」語は無い。代わりに、「いつ」の列を聞く範囲で切り、出てきた点を数える。定義は「いつでも成り立つ規則」、範囲は「いつからいつまで聞くか」——前回の §5 で書いた分け方が、ここでは数える道具になる。
2. 営業日を数える——列を [今日, 締め切り日) で聞く
祝日表と営業日の列を前文に置く(「月 2 回」の回の §3 と同じ)。本体は bizDay だけ:
premise JP {
calendar-system: Gregorian; tz: "Asia/Tokyo"; wkst: Mon
national = [2026-01-01, 2026-01-12, 2026-02-11, 2026-02-23, 2026-03-20, 2026-04-29, 2026-05-03..2026-05-06,
2026-07-20, 2026-08-11, 2026-09-21..2026-09-23, 2026-10-12, 2026-11-03, 2026-11-23] covering: 2026..2026
satSun = everyDay |> filter(d => weekday(d) == Sat or weekday(d) == Sun)
bizDay = everyDay \ (satSun | national)
}
@JP
bizDay
今日から締め切り日の手前まで:
$ kairos list --from 2026-10-26 --to 2026-11-04 days.kairos 2026-10-26 2026-10-27 2026-10-28 2026-10-29 2026-10-30 2026-11-02 # 被覆サマリ # JP.national covering 2026-01-01..2026-12-31 残走路 58 日
6 行。10 月 31 日・11 月 1 日の土日と、11 月 3 日の文化の日が落ちている。締め切り当日も数えるなら --to 2026-11-05 で 7 行。from, to) は右端を含まない([半開区間の回)ので、「当日を含めるか」は --to を 1 日ずらすだけで決まる。

数えるのは呼ぶ側の仕事で、--json で受ければ行数を数えるだけになる:
$ kairos list --from 2026-10-26 --to 2026-11-04 --json days.kairos | jq '.results[0].dates | length' 6
PowerShell なら (kairos list … --json days.kairos | ConvertFrom-Json).results[0].dates.Count。
3. 営業時間を数える——正時の点を isOpen で絞る
「あと何時間」は、営業時間内の毎正時を点にして数える。会社の営業時間を 9 時から 17 時として、営業時間の定義はisOpen の回の器をそのまま使う:
premise Office {
calendar-system: Gregorian
tz: "Asia/Tokyo"
source: "example"
satSunC = everyDay |> filter(d => weekday(d) == Sat or weekday(d) == Sun)
holidays = [2026-10-12, 2026-11-03, 2026-11-23] covering: 2026-10-01..2026-12-31
nonWorking = satSunC | holidays
nine = chronos grid 1d anchor: 2026-01-01T09:00
five = chronos grid 1d anchor: 2026-01-01T17:00
sessionOpens = nine |> first
sessionCloses = five |> first
}
premise JP {
calendar-system: Gregorian
calendar: Office
tz: "Asia/Tokyo"
wkst: Mon
hourly = everyInstant |> strideBy(1h, from: 2026-01-01)
}
@JP
hourly |> filter(t => isOpen(t))
hourly は毎正時の列、isOpen(t) は「その瞬間に開いているか」。9 時から 17 時の手前までで、1 日 8 点。[2026-10-26, 2026-11-04) で聞くと営業日 6 日 × 8 点 = 48 点が出る。
ただし、これでは「今日の 14 時まで」の分と「締め切り当日の 17 時まで」の分が合わない。--from・--to は日付で指定するので、時刻の切り出しは式の中で書く。「時」の通し番号(epochOrdinal(hour, t))を比べる:
hourly |> filter(t => isOpen(t) and epochOrdinal(hour, t) >= epochOrdinal(hour, 2026-10-26T14:00) and epochOrdinal(hour, t) < epochOrdinal(hour, 2026-11-04T17:00))
$ kairos list --from 2026-10-26 --to 2026-11-05 hours.kairos 2026-10-26T14:00 2026-10-26T15:00 2026-10-26T16:00 2026-10-27T09:00 (略) 2026-11-04T15:00 2026-11-04T16:00 # 被覆サマリ # Office.holidays covering 2026-10-01..2026-12-31 残走路 57 日
51 行。今日の残り 3 点(14・15・16 時)、間の 5 営業日で 40 点、締め切り当日の 8 点(9 時から 16 時)。「14 時から」と「17 時の手前まで」が、それぞれ >= と < に写っている。
4. 落とし穴
- 「51 時間」は正時の点の数。14 時 30 分に聞いても、14 時台のコマは 1 つと数える。分単位の端数が要るなら、 「数えるコマの幅」を先に決める(
strideBy(30m, …)にすれば 30 分刻みで 102 点)。 - 祝日表の期限。被覆サマリの「残走路 57 日」は、祝日表が 12 月末で切れていることを言っている。年を跨ぐ締め切りを 数える前に表を延ばす(祝日表は黙って腐る)。
- 会議や移動を引くなら、前回の
\の型。会議の列を正時の点で作ってhourly \ meetingsと引けば、「使える時間」に近づく。ただし 30 分の会議を 1 時間のコマから引くかどうかは、書き手が決める。 - 「今」は式に埋めない。
2026-10-26T14:00は例のために直書きしたが、毎朝聞くなら呼ぶ側が今日の日付を--fromに 入れ、時刻の切り出しは定義に書かずに--jsonで受けた点を手元で切る方が素直である。
5. 動かす
毎朝 9 時に「残り営業日」を数えて知らせるなら、月末最終営業日の自動実行まで通すの型 1 で--from を今日、--to を締め切り日にする。Windows ならWindows Update の回の §6 のガイドのPowerShell が、--json を ConvertFrom-Json で受けて .Count を取るところまで同じ型で書ける。
まとめ
- 「あと何日」には暦の日数・営業日・使える時間の 3 つの答えがある。Kairos に「残りを返す」語は無く、列を範囲で切って点を数える
- 営業日:
bizDayを[今日, 締め切り日)で聞く。当日を含めるかは--toを 1 日ずらす - 営業時間:
hourly |> filter(t => isOpen(t))で 1 日 8 点。時刻の切り出しはepochOrdinal(hour, …)の比較で式に書く - 「51 時間」は正時のコマの数。端数の扱いと会議の除外は書き手が決める
- 数えるのは呼ぶ側。
--jsonで受けて行数を数える
▶ Playground で定義を実行する——10 月 26 日 14 時から 11 月 4 日 17 時までの営業時間 51 点が出る。コメントにある bizDay の行と入れ替えると営業日 7 点(締め切り当日を含む)になる。ブラウザ内で完結し、何も送信しない。
Kairos はスケジュール定義言語です——決めたら、いつでも。仕様と参照実装はGitHub で公開しています。

コメント