Small custom coach view: two bound dates in, a number out. Keep the calculation in one function and run it on every change.
// Coach view "Date Difference"
// configuration options: fromDate (Date), toDate (Date), unit (String: days|hours|businessDays) binding: Decimal (the result)
// Layout: <span class="diff"></span>
// load handler
var me = this;
me.calc = function () {
var a = me.context.options.fromDate.get("value"), b = me.context.options.toDate.get("value");
if (!a || !b) { me.context.binding.set("value", null); return; }
a = new Date(a); b = new Date(b);
var unit = me.context.options.unit.get("value") || "days", diff;
if (unit === "hours") diff = (b - a) / 36e5;
else if (unit === "businessDays") { diff = 0; var d = new Date(a); while (d < b) { d.setDate(d.getDate() + 1); if (d.getDay() % 6 !== 0) diff++; } }
else diff = Math.round((Date.UTC(b.getFullYear(), b.getMonth(), b.getDate()) - Date.UTC(a.getFullYear(), a.getMonth(), a.getDate())) / 864e5);
me.context.binding.set("value", diff);
me.context.element.querySelector(".diff").textContent = diff + " " + unit;
};
me.calc();
// change handler (options or binding changed): me.calc();Wire it up in the CSHS: two Date Time Picker controls bound to tw.local.start and tw.local.end, the view's options bound to the same variables, its binding to tw.local.days. Because the options are bound, the view's change event fires when either picker changes - no button needed.
Without a custom view: a Text control with a UI Toolkit formula does the simple case: Math.round((${End}.getDate() - ${Start}.getDate()) / 864e5) (Spark formulas re-evaluate when the referenced controls change).
References