Reads task dates from a schedule file and says, for a date, which elements are built, in progress or not started.
How the precision is kept
Dates are whole day numbers since 1970-01-01 (UTC), so every comparison is between integers. A day that does not exist (2026-02-30) is refused.
Calculations under this policy
3 calculations in 1 source file. The code is read from the released app when this page loads. It is the calculation people run, not a copy kept for this page.
A YYYY-MM-DD date as a count of days since 1970-01-01.
day = Date.UTC(y, m, d) ÷ 86400000
Midnight UTC is a whole multiple of 86,400,000 ms, so the quotient is an integer; Math.round changes nothing. The date is built back and compared to refuse days that do not exist.
ifc-4d.js
lines 36 to 43
BimCraft 0.8.1
export function parseDay(s) {
const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(String(s ?? '').trim());
if (!m) return null;
const d = Date.UTC(+m[1], +m[2] - 1, +m[3]);
const back = new Date(d);
if (back.getUTCFullYear() !== +m[1] || back.getUTCMonth() !== +m[2] - 1 || back.getUTCDate() !== +m[3]) return null; // 2026-02-30
return Math.round(d / 86400000);
}
Built, in progress or waiting on a date
Exact
The state of every element that belongs to a task, on a chosen day.
built if day > finish; in progress if start ≤ day ≤ finish; waiting if day < start
Integer comparisons of day numbers. An element in several tasks is built only when every task is, and in progress when some are built and others not started.
ifc-4d.js
lines 127 to 136
BimCraft 0.8.1
export function statusAt(matched, day) {
const all = new Map(); // key → [built, progress, waiting] counts over its tasks
for (const t of matched) {
const i = day > t.finish ? 0 : day >= t.start ? 1 : 2; // in progress from Start through Finish, built the day after
for (const k of t.keys) { let c = all.get(k); if (!c) all.set(k, (c = [0, 0, 0])); c[i]++; }
}
const st = new Map();
for (const [k, c] of all) st.set(k, c[1] || (c[0] && c[2]) ? 'progress' : c[0] ? 'built' : 'waiting'); // built in one task, not started in another: still being worked on
return st;
}
Task counts of a stage or package
Exact
How many tasks of a group are done, running and still to do on a day.
Integer comparisons and counts.
ifc-4d.js
lines 185 to 189
BimCraft 0.8.1
export function groupState(tasks, day) {
const n = { done: 0, now: 0, todo: 0 };
for (const t of tasks) n[day > t.finish ? 'done' : day >= t.start ? 'now' : 'todo']++;
return n;
}
In detail
Method
day = milliseconds at 00:00 UTC ÷ 86,400,000. A task is in progress from its start day through its finish day and built from the day after.
Number types
Integers held in 64-bit numbers.
Limits
Dates only: no time of day and no time zones.
Approach: Exact values
Constants and factors are held as exact fractions from their definitions. The arithmetic is ordered so that no rounded factor is ever used.