Changeset 421c2d4 in Klonkt for src/views/pages/post-edit.ejs


Ignore:
Timestamp:
06/21/2026 04:48:27 PM (3 months ago)
Author:
roboburr <roboburr@…>
Branches:
main
Children:
d6bdbae
Parents:
9effb80
Message:

feat(instellingen): site timezone — all dates + scheduling in chosen zone

Admin → Settings gets a Timezone picker (IANA, validated via Intl; empty =
server/UTC). Applied to: server-side date display (formatDate/formatDateTime
receive timeZone), and post scheduling (datetime-local is now interpreted/shown
in the site's zone instead of browser-local — wall↔UTC via Intl offset).
'Scheduled for' shows the time in the site's zone. NL/EN/DE.

Co-Authored-By: Claude <noreply@…>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/views/pages/post-edit.ejs

    r9effb80 r421c2d4  
    225225              if (!cb || !box) return;
    226226              var inp = document.getElementById('pe-publish-at');
     227              var SITE_TZ = '<%= timezone || '' %>'; // ingestelde site-tijdzone; leeg = browser-lokaal
    227228              var pad = function (n) { return String(n).padStart(2, '0'); };
    228               // Prefill: opgeslagen UTC → lokale datetime-local-waarde (zodat je je
    229               // eigen tijdzone ziet, niet UTC).
    230               if (inp && inp.dataset.iso) {
    231                 var d0 = new Date(inp.dataset.iso);
    232                 if (!isNaN(d0)) inp.value = d0.getFullYear() + '-' + pad(d0.getMonth() + 1) + '-' + pad(d0.getDate()) + 'T' + pad(d0.getHours()) + ':' + pad(d0.getMinutes());
     229              // Offset (ms) tussen een tijdzone en UTC op een bepaald moment.
     230              function tzOffset(date, tz) {
     231                var f = new Intl.DateTimeFormat('en-US', { timeZone: tz, hour12: false, year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit' });
     232                var p = {}; f.formatToParts(date).forEach(function (x) { p[x.type] = x.value; });
     233                return Date.UTC(+p.year, +p.month - 1, +p.day, +p.hour, +p.minute, +p.second) - date.getTime();
    233234              }
    234               // "Ingepland voor" in leesbare lokale tijd i.p.v. ruwe UTC-ISO.
     235              // datetime-local "wandtijd" (in de site-zone) → UTC Date.
     236              function wallToUtc(wall) {
     237                if (!SITE_TZ) return new Date(wall);
     238                var guess = new Date(wall + ':00Z').getTime();
     239                return new Date(guess - tzOffset(new Date(guess), SITE_TZ));
     240              }
     241              // UTC-ISO → "YYYY-MM-DDTHH:MM" wandtijd in de site-zone.
     242              function utcToWall(iso) {
     243                var d = new Date(iso); if (isNaN(d)) return '';
     244                if (!SITE_TZ) return d.getFullYear() + '-' + pad(d.getMonth() + 1) + '-' + pad(d.getDate()) + 'T' + pad(d.getHours()) + ':' + pad(d.getMinutes());
     245                var f = new Intl.DateTimeFormat('en-CA', { timeZone: SITE_TZ, hour12: false, year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' });
     246                var p = {}; f.formatToParts(d).forEach(function (x) { p[x.type] = x.value; });
     247                return p.year + '-' + p.month + '-' + p.day + 'T' + p.hour + ':' + p.minute;
     248              }
     249              // Prefill: opgeslagen UTC → wandtijd in de site-zone.
     250              if (inp && inp.dataset.iso) inp.value = utcToWall(inp.dataset.iso);
     251              // "Ingepland voor" in leesbare tijd van de site-zone.
    235252              var when = document.getElementById('pe-sched-when');
    236253              if (when && when.dataset.iso) {
    237254                var dw = new Date(when.dataset.iso);
    238                 if (!isNaN(dw)) when.textContent = '⏳ ' + when.dataset.label + ' ' + dw.toLocaleString();
     255                if (!isNaN(dw)) when.textContent = '⏳ ' + when.dataset.label + ' ' + dw.toLocaleString(undefined, SITE_TZ ? { timeZone: SITE_TZ } : undefined);
    239256              }
    240257              function sync() { box.style.display = cb.checked ? '' : 'none'; if (inp) inp.disabled = !cb.checked; }
    241258              cb.addEventListener('change', sync); sync();
    242               // Bij opslaan: lokale invoer → UTC-ISO via een hidden veld, zodat de
    243               // server de juiste tijd opslaat (datetime-local heeft geen tijdzone).
     259              // Bij opslaan: wandtijd in de site-zone → UTC-ISO via een hidden veld.
    244260              var form = cb.closest('form');
    245261              if (form) {
     
    249265                  if (old) old.remove();
    250266                  if (cb.checked && inp && inp.value) {
    251                     var d2 = new Date(inp.value); // geïnterpreteerd in browser-tijdzone
     267                    var d2 = wallToUtc(inp.value);
    252268                    if (!isNaN(d2)) {
    253269                      var h = document.createElement('input');
Note: See TracChangeset for help on using the changeset viewer.