timeFrom(new Date('2015/12/31'), document.querySelector("#timedFrom")); timeUntil(new Date('2019/12/31 23:59'), document.querySelector("#timedUntil")); function timeFrom(fromDate, fromField) { const writer = (difference, dtElements) => ` <div>From ${fromDate.toLocaleString()} to now lasted</div>${ dtElements.day(difference.days)} ${ dtElements.hour(difference.hours)} ${ dtElements.minute(difference.minutes)} and ${ dtElements.second(difference.seconds)}`; countUpOrDown().createAndStartTimer(fromField, fromDate, writer); } function timeUntil(untilDate, untilField) { const date2Show = untilDate.toLocaleString(); const writer = (difference, dtElements) => ` <div>Time until ${date2Show}</div>${ dtElements.day(difference.days)} ${ dtElements.hour(difference.hours)} ${ dtElements.minute(difference.minutes)} and ${ dtElements.second(difference.seconds)}`; const cb = () => { const el = document.createElement("div"); el.appendChild(document.createTextNode(`${date2Show} passed`)); untilField.appendChild(el); }; countUpOrDown().createAndStartTimer(untilField, untilDate, writer, cb); } function countUpOrDown() { const logTo = (field, args) => field.innerHTML = args; const dtElements = dateTimeFragments(); const writerFactory = (field, writer, value) => diff => logTo(field, writer(diff, dtElements)); const createTimer = (field, dateValue, writer, callback) => counterFactory(dateValue, writerFactory(field, writer, dateValue), callback) return { createTimer: createTimer, createAndStartTimer: (...args) => createTimer.call(null, ...args)() }; function counterFactory(value, writer, callback) { const showTime = () => { const diffMS = value - new Date(); const reIterate = () => { writer(dateDiffCalc(diffMS)); setTimeout(showTime, 1000); }; const exitCounter = () => callback instanceof Function && callback(); return diffMS <= 0 && callback ? exitCounter() : reIterate(); }; return showTime; } function dateDiffCalc(milliseconds) { let secs = Math.floor(Math.abs(milliseconds) / 1000); let mins = Math.floor(secs / 60); let hours = Math.floor(mins / 60); let days = Math.floor(hours / 24); const millisecs = Math.floor(Math.abs(milliseconds)) % 1000; return { days: days, hours: hours % 24, minutes: mins % 60, seconds: secs % 60, milliSeconds: millisecs, }; } function dateTimeFragments() { const pad = (val, width = 2) => val < 1 ? val : String(val).padStart(width, "0"); const plural = (val, term) => `${term}${val !== 1 ? "s" : ""}`; const checkZero = (val, term, comma) => val < 1 ? "" : `<b>${pad(val)}</b> ${plural(val, term)}${comma ? ", " : ""}`; return { day: d => checkZero(d, "day", 1), hour: h => checkZero(h, "hour", 1), minute: m => `<b>${pad(m)}</b> ${plural(m, "minute")}`, second: s => `<b>${pad(s)}</b> ${plural(s, "second")}` }; } }
<div id="timedUntil" data-timer></div> <div id="timedFrom" data-timer></div>
body { font: 16px/20px normal verdana, arial, helvetica; margin: 1.5em; } [data-timer] { margin-bottom: 0.7em; } [data-timer] div:first-child { font-style: italic; color: #AAA; } [data-timer] b { color: green; }