JSFiddle - React, Tailwind, and code Playground

by hexag0n

HTML

<table>
  <tr>
    <td colspan="3">
      <h2>
        Time zone converter
      </h2>
    </td>
  </tr>
  <tr class="big">
    <td>Source time</td>
    <td>Source time zone</td>
    <td>Destination time zone</td>
  </tr>
  <tr class="small">
    <td>ISO8601-ish string format</td>
    <td>IANA TZ Database format</td>
    <td>IANA TZ Database format</td>
  </tr>
  <tr>
    <td><input placeholder="2022-09-01 23:00:00" id="sourceDate"></td>
    <td><select id="sourceTz"></select></td>
    <td><select id="destTz"></select></td>
  </tr>
  <tr>
    <td colspan="3">
      <h3>Result</h3>
    </td>
  </tr>
  <tr class="big">
    <td colspan="3" id="result"></td>
  </tr>
  <tr class="small">
    <td colspan="3" id="error"></td>
  </tr>
</table>

CSS

td {
  padding-right: 1rem;
  text-align: center;
}

.small td {
  font-size: 0.75rem;
}

.big td {
  font-size: 1.25rem;
  font-family: monospace;
}

JavaScript

import { minitz } from "https://cdn.jsdelivr.net/gh/hexagon/minitz@3.0.0/dist/minitz.min.mjs";

// Handle custome time zone conversion
let allTimezones = Intl.supportedValuesOf('timeZone'),
  inputTimeElm = document.getElementById('sourceDate'),
  resultElm = document.getElementById('result'),
  errorElm = document.getElementById('error'),
  sourceTzElm = document.getElementById('sourceTz'),
  destTzElm = document.getElementById('destTz');

allTimezones.forEach((t) => {
  sourceTzElm.appendChild(new Option(t, t));
  destTzElm.appendChild(new Option(t, t));
});

const recalculate = () => {
  let result = "Error",
    errorMessage = "";
  try {
    result = minitz.fromTZISO(inputTimeElm.value, sourceTzElm.value).toLocaleString('sv-SE', {
      timeZone: destTzElm.value
    });
  } catch (e) {
    errorMessage = e.toString();
  }
  resultElm.innerHTML = result;
  errorElm.innerHTML = errorMessage;
};

inputTimeElm.addEventListener('change', () => {
  recalculate()
});
inputTimeElm.addEventListener('keypress', () => {
  recalculate()
});
sourceTzElm.addEventListener('change', () => {
  recalculate()
});
destTzElm.addEventListener('change', () => {
  recalculate()
});

// Seed input time element with current time
inputTimeElm.value = new Date().toLocaleString('sv-SE');

// Recalculate instantly
recalculate();