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;
}