Edit in JSFiddle

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