Time until/from counter UTC

Show time until or from a certain date (factories), UTC

by KooiInc MeHere

HTML

<h3>
  Count down or up to a given <i>UTC</i>-date
</h3>
<div id="timedUntil" data-timer></div>
<p>
  <div>
    <b>Next timer continues after the time has passed</b>
  </div>
  <div id="timedUntil2" data-timer></div>
</p>
<h3>
  Time until next new year
</h3>
<div id="timedUntilNewYear" data-timer></div>

<h3>
  The current year now lasts
</h3>
<div id="timedFromLastNewYear" data-timer></div>

CSS

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

h3 {
  margin-bottom: 0.3rem;
  min-width: 200px;
  text-decoration: underline;
}

JavaScript

const {
  dtFrags,
  dateAdd,
  dateSubtract,
} = DateAddFactory();
const [until0, until1, toNwYr, fromNwYr] = 
	[...document.querySelectorAll(`#timedUntil, #timedUntil2, #timedUntilNewYear, #timedFromLastNewYear`)];
const thisYearsNewYear = new Date(Date.UTC(new Date().getFullYear(), 11, 31));
const timer = TimerFactory();

time(thisYearsNewYear, toNwYr, timer);
time(dateSubtract(dtFrags.year, 1, thisYearsNewYear), fromNwYr, timer);
time(dateAdd(dtFrags.seconds, 5), until0, timer);
time(dateAdd(dtFrags.seconds, 10), until1, timer, true);

function time(date, reportField, timer, continueAfterPassed = false) {
  const isFuture = timer.toUTC(date) - timer.toUTC(new Date()) > 0;
  const stopGo = {
    stop: () => reportField.textContent = `${dateStr} passed`,
    go: () => time(date, reportField, timer),
  };
  const dateStr = new Date(date).toUTCString();
  const initStr = isFuture ?
    `<div>Time until ${dateStr}</div>` :
    `<div>From ${dateStr} until now lasted</div>`;
  const passed = isFuture && !continueAfterPassed ? stopGo.stop : isFuture ? stopGo.go : null;
  const writer = (difference, dtElements) => `
      ${initStr}${
        dtElements.day(difference.days)} ${dtElements.hour(difference.hours)} ${
        dtElements.minute(difference.minutes)} and ${dtElements.second(difference.seconds)}`;
  return timer.createAndStartTimer(reportField, date, writer, passed);
}

function TimerFactory() {
  const toUTC = someDate => Date.UTC(
    someDate.getUTCFullYear(), someDate.getUTCMonth(), someDate.getUTCDate(),
    someDate.getUTCHours(), someDate.getUTCMinutes(), someDate.getUTCSeconds());
  const logTo = (field, args) => field.innerHTML = args;
  const dtElements = dateTimeFragments(false);
  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 {
   ...