Files
oslstats/internal/embedfs/web/js/localtime.js

85 lines
2.6 KiB
JavaScript

// localtime.js - Converts UTC <time> elements to the user's local timezone.
//
// Usage: <time datetime="2026-01-14T10:30:00Z" data-localtime="datetime">fallback</time>
//
// Supported data-localtime values:
// "date" → "Mon 2 Jan 2026"
// "time" → "3:04 PM"
// "datetime" → "Mon 2 Jan 2026 at 3:04 PM"
// "short" → "Mon 2 Jan 3:04 PM"
// "histdate" → "2 Jan 2006 15:04"
(function () {
const SHORT_DAYS = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
const SHORT_MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
function pad(n) { return n < 10 ? '0' + n : '' + n; }
function formatTime12(d) {
let h = d.getHours();
const m = pad(d.getMinutes());
const ampm = h >= 12 ? 'PM' : 'AM';
h = h % 12 || 12;
return h + ':' + m + ' ' + ampm;
}
function formatDate(d) {
return SHORT_DAYS[d.getDay()] + ' ' + d.getDate() + ' ' +
SHORT_MONTHS[d.getMonth()] + ' ' + d.getFullYear();
}
function formatLocalTime(el) {
const iso = el.getAttribute('datetime');
if (!iso) return;
const d = new Date(iso);
if (isNaN(d.getTime())) return;
const fmt = el.getAttribute('data-localtime');
let text;
switch (fmt) {
case 'date':
text = formatDate(d);
break;
case 'time':
text = formatTime12(d);
break;
case 'datetime':
text = formatDate(d) + ' at ' + formatTime12(d);
break;
case 'short':
text = SHORT_DAYS[d.getDay()] + ' ' + d.getDate() + ' ' +
SHORT_MONTHS[d.getMonth()] + ' ' + formatTime12(d);
break;
case 'histdate':
text = d.getDate() + ' ' + SHORT_MONTHS[d.getMonth()] + ' ' +
d.getFullYear() + ' ' + pad(d.getHours()) + ':' + pad(d.getMinutes());
break;
default:
text = formatDate(d) + ' at ' + formatTime12(d);
}
el.textContent = text;
// Add timezone tooltip so users know the displayed time is in their local timezone
var tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
el.title = 'Displayed in your local timezone (' + tz + ')';
}
function processAll(root) {
const els = (root || document).querySelectorAll('time[data-localtime]');
els.forEach(formatLocalTime);
}
// Process on page load
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function () { processAll(); });
} else {
processAll();
}
// Re-process after HTMX swaps
document.addEventListener('htmx:afterSettle', function (evt) {
processAll(evt.detail.elt);
});
})();