KoderKoder.ai
PrezziEnterpriseIstruzionePer gli investitori
AccediInizia ora

Prodotto

PrezziEnterprisePer gli investitori

Risorse

ContattaciAssistenzaIstruzioneBlog

Note legali

Informativa sulla privacyTermini di utilizzoSicurezzaNorme di utilizzoSegnala un abuso

Social

LinkedInTwitter
Koder.ai
Lingua

© 2026 Koder.ai. Tutti i diritti riservati.

Home›Blog›Formattazione e conversione del tempo in JavaScript: errori comuni
06 set 2025·8 min

Formattazione e conversione del tempo in JavaScript: errori comuni

Impara a formattare e convertire il tempo in JavaScript senza sorprese: timestamp, stringhe ISO, fusi orari, ora legale, regole di parsing e pattern affidabili.

Formattazione e conversione del tempo in JavaScript: errori comuni

Cosa va storto di solito con il tempo in JavaScript

I bug legati al tempo in JavaScript raramente si manifestano come “l'orologio è sbagliato”. Si presentano come piccoli scostamenti puzzolenti: una data corretta sul tuo portatile ma sbagliata sul computer di un collega, una risposta API che sembra giusta finché non viene renderizzata in un altro fuso orario, o un report che è “sbagliato di un giorno” intorno a un cambio stagionale.

I sintomi più comuni

Di solito noterai uno (o più) di questi:

  • Spostamento di un'ora: specialmente attorno all'ora legale, o quando un valore viene involontariamente convertito tra ora locale e UTC.
  • Spostamento di un giorno: un valore che rappresenta solo la data (es. “2025-12-23”) appare il giorno precedente/successivo a seconda del fuso orario.
  • Fuso orario sbagliato: gli orari sembrano corretti, ma l'offset (per esempio +02:00) è diverso da quanto ci si aspettava.
  • Formattazione incoerente: “funziona in Chrome” ma appare diverso in Safari, o server e browser non sono d'accordo su come interpretare una stringa.

Perché succede: “tempo” può significare cose diverse

Una grande fonte di dolore è che la parola tempo può riferirsi a concetti diversi:

  • Un istante: un momento specifico a livello mondiale (es. “2025-12-23T10:00:00Z”). Questo è ciò che di solito vuoi per logging, eventi e storage API.
  • Una data di calendario: un giorno sul calendario senza fuso orario (es. un compleanno, la data di una fattura). Trattarla come un istante può spostarla oltre i confini di giorno.
  • Ora sul quadrante: “9:00 a.m. a Berlino”, che dipende dalle regole del fuso orario e dai cambi dell'ora legale.

Il Date incorporato in JavaScript cerca di coprire tutti questi casi, ma rappresenta principalmente un istante nel tempo mentre ti spinge continuamente verso la visualizzazione locale, il che rende facili le conversioni accidentali.

Su cosa si concentra questo articolo

Questa guida è intenzionalmente pratica: come ottenere conversioni prevedibili tra browser e server, come scegliere formati più sicuri (come ISO 8601) e come individuare le trappole classiche (secondi vs millisecondi, UTC vs locale e differenze di parsing). L'obiettivo non è più teoria, ma meno sorprese del tipo “perché si è spostato?”.

Tipi di dati temporali: Timestamp, Date e Stringa

I bug temporali in JavaScript spesso iniziano mescolando rappresentazioni che sembrano intercambiabili, ma non lo sono.

Le tre rappresentazioni che vedrai più spesso

1) Epoch milliseconds (numero)

Un numero semplice come 1735689600000 è tipicamente “millisecondi dal 1970-01-01T00:00:00Z”. Rappresenta un istante nel tempo senza formattazione o fuso orario.

2) Oggetto Date (wrapper attorno a un istante)

Un Date memorizza lo stesso tipo di istante di un timestamp. La parte confusa: quando stampi un Date, JavaScript lo formatta usando le regole locali dell'ambiente a meno che non chiedi diversamente.

3) Stringa formattata (visualizzazione umana)

Stringhe come "2025-01-01", "01/01/2025 10:00", o "2025-01-01T00:00:00Z" non sono tutte la stessa cosa. Alcune sono inequivocabili (ISO 8601 con Z), altre dipendono dalla locale, e alcune non includono affatto il fuso orario.

“Istante nel tempo” vs “ora per l'utente”

  • Istante nel tempo: “questo preciso momento a livello globale” (meglio memorizzarlo come epoch ms o come stringa ISO in UTC).
  • Ora per l'utente: “ciò che l'utente deve vedere” (dipende da locale e fuso orario).

Lo stesso istante può essere mostrato diversamente a seconda del fuso orario:

const instant = new Date("2025-01-01T00:00:00Z");

instant.toLocaleString("en-US", { timeZone: "UTC" });
// "1/1/2025, 12:00:00 AM"

instant.toLocaleString("en-US", { timeZone: "America/Los_Angeles" });
// "12/31/2024, 4:00:00 PM" (giorno precedente)

Scegli una “fonte di verità”

Scegli una sola rappresentazione interna (comunemente epoch milliseconds o ISO 8601 UTC) e mantienila in tutta l'app e nelle API. Converti verso/da Date e stringhe formattate solo ai confini: parsing dell'input e visualizzazione in UI.

Timestamp: secondi vs millisecondi (facile confonderli)

Un “timestamp” solitamente significa tempo epoch (detto anche Unix time): il conteggio del tempo a partire da 1970-01-01 00:00:00 UTC. Il problema: sistemi diversi usano unità diverse.

Il Date di JavaScript è la fonte della maggior parte della confusione perché usa millisecondi. Molte API, database e log usano secondi.

Regola pratica

  • Unix timestamp (secondi): 1704067200
  • JavaScript timestamp (millisecondi): 1704067200000

Stesso momento, ma la versione in millisecondi ha tre cifre in più.

Conversioni sicure (secondi ↔ millisecondi)

Usa moltiplicazioni/divisioni esplicite così l'unità è ovvia:

// seconds -> Date
const seconds = 1704067200;
const d1 = new Date(seconds * 1000);

// milliseconds -> Date
const ms = 1704067200000;
const d2 = new Date(ms);

// Date -> seconds
const secondsOut = Math.floor(d2.getTime() / 1000);

// Date -> milliseconds
const msOut = d2.getTime();

Il bug classico: passare secondi a Date()

Questo sembra ragionevole, ma è sbagliato quando ts è in secondi:

const ts = 1704067200;      // seconds
const d = new Date(ts);     // WRONG: treated as milliseconds

Il risultato sarà una data nel 1970, perché 1,704,067,200 millisecondi sono solo circa 19 giorni dopo l'epoch.

Controlli rapidi per debug

Quando non sei sicuro dell'unità che hai, aggiungi guardrail rapidi:

function asDateFromUnknownEpoch(x) {
  // crude heuristic: seconds are ~1e9-1e10, milliseconds are ~1e12-1e13
  if (x < 1e11) return new Date(x * 1000); // assume seconds
  return new Date(x);                      // assume milliseconds
}

const input = Number(valueFromApi);
console.log({ input, digits: String(Math.trunc(input)).length });
console.log('as ISO:', asDateFromUnknownEpoch(input).toISOString());

Se il conteggio delle “cifre” è ~10 probabilmente sono secondi. Se è ~13 probabilmente sono millisecondi. Stampare toISOString() durante il debug aiuta a individuare immediatamente errori di unità.

Ora locale vs UTC: perché l'output si sposta

Il Date di JavaScript può essere confuso perché memorizza un singolo istante nel tempo, ma può presentare quell'istante in fusi orari diversi.

Internamente, un Date è essenzialmente “millisecondi dall'epoch Unix (1970-01-01T00:00:00Z)”. Quel numero rappresenta un momento in UTC. Lo “spostamento” avviene quando chiedi a JavaScript di formattare quell'istante come ora locale (basata sulle impostazioni del computer/server) invece che in UTC.

Metodi locali vs metodi UTC

Molte API di Date hanno varianti locali e UTC. Restituiscono numeri diversi per lo stesso istante:

const d = new Date('2025-01-01T00:30:00Z');

d.getHours();      // hour in *local* time zone
d.getUTCHours();   // hour in UTC

d.toString();      // local time string
d.toISOString();   // UTC (always ends with Z)

Se la tua macchina è a New York (UTC-5), quell'ora UTC può apparire come “19:30” del giorno precedente in locale. Su un server impostato su UTC apparirà come “00:30”. Stesso istante, visualizzazioni diverse.

Perché i log sembrano “sbagliati”

I log spesso usano Date#toString() o interpolano un Date implicitamente, che utilizza il fuso orario locale dell'ambiente. Questo significa che lo stesso codice può stampare timestamp diversi sul tuo laptop, in CI e in produzione.

Indicazioni pratiche

Memorizza e trasmetti il tempo in UTC (es. epoch milliseconds o ISO 8601 con Z). Convertilo nella locale dell'utente solo quando mostri i dati:

  • Per le API: preferisci toISOString() o invia epoch milliseconds
  • Per la UI: formatta nel fuso orario dell'utente usando Intl.DateTimeFormat

Se costruisci un'app rapidamente, aiuta definire questo nei contratti API generati in anticipo: nomina chiaramente i campi (createdAtMs, createdAtIso) e mantieni server (Go + PostgreSQL) e client (React) coerenti su cosa rappresenta ogni campo.

Stringhe ISO 8601: il formato più sicuro per le API

Se devi inviare date/tempi tra browser, server e database, le stringhe ISO 8601 sono il default più sicuro. Sono esplicite, ampiamente supportate e (soprattutto) contengono informazioni sul fuso orario.

Usa UTC esplicito o un offset esplicito

Due buoni formati di scambio:

  • Ora UTC (raccomandato quando il fuso locale non importa): 2025-03-04T12:30:00Z
  • Ora locale con offset (raccomandato quando l'ora sul quadrante locale conta): 2025-03-04T12:30:00+02:00

Cosa significa “Z”?

Z sta per Zulu time, un altro nome per UTC. Quindi 2025-03-04T12:30:00Z è “12:30 in UTC”.

Quando gli offset come +02:00 sono importanti?

Gli offset sono cruciali quando un evento è legato a un contesto di fuso locale (appuntamenti, prenotazioni, orari di apertura). 2025-03-04T12:30:00+02:00 descrive un istante che è due ore avanti rispetto a UTC, e non è lo stesso istante di 2025-03-04T12:30:00Z.

Evita stringhe ambigue

Stringhe come 03/04/2025 sono una trappola: è il 4 marzo o il 3 aprile? Diversi utenti ed ambienti lo interpretano in modo diverso. Preferisci 2025-03-04 (data ISO) o un datetime ISO completo.

Round-trip sicuro (stringa → Date → stringa)

const iso = "2025-03-04T12:30:00Z";
const d = new Date(iso);
const back = d.toISOString();

console.log(iso);  // 2025-03-04T12:30:00Z
console.log(back); // 2025-03-04T12:30:00.000Z

Quel comportamento di “round-trip” è esattamente ciò che vuoi per le API: consistente, prevedibile e consapevole del fuso orario.

Trappole del parsing: Date.parse e differenze tra browser

Make logs predictable everywhere
Genera utilità di logging e formattazione con priorità UTC che funzionano uguali in dev, CI e produzione.
Costruisci ora

Date.parse() sembra comodo: gli passi una stringa e ottieni un timestamp. Il problema è che per tutto ciò che non è chiaramente ISO 8601, il parsing può dipendere da euristiche del browser. Quelle euristiche sono cambiate tra motori e versioni, il che significa che lo stesso input può essere interpretato diversamente (o non interpretato) a seconda di dove gira il codice.

Perché Date.parse() può variare

JavaScript standardizza il parsing in modo affidabile solo per stringhe stile ISO 8601 (e anche lì dettagli come il fuso orario contano). Per formati “friendly” — come "03/04/2025", "March 4, 2025" o "2025-3-4" — i browser possono interpretare:

  • Mese/giorno vs giorno/mese basandosi su assunzioni di locale
  • L'assenza del fuso orario come ora locale in un motore, ma rifiutata in un altro
  • Stringhe leggermente malformate come “abbastanza vicine”… finché non lo sono

Se non puoi prevedere la forma esatta della stringa, non puoi prevedere il risultato.

Il caso sorprendente: YYYY-MM-DD

Una trappola comune è la forma "YYYY-MM-DD" (per esempio, "2025-01-15"). Molti sviluppatori si aspettano che venga interpretata come mezzanotte locale. In pratica, alcuni ambienti trattano questa forma come mezzanotte UTC.

Questa differenza conta: la mezzanotte UTC convertita in ora locale può diventare il giorno precedente in zone negative (es. Americhe) o spostare l'ora inaspettatamente. È un modo facile per ottenere bug “perché la mia data è sbagliata di un giorno?”.

Checklist di parsing: input utente vs input server

Per input server/API:

  • Preferisci ISO 8601 completo con fuso esplicito, es. 2025-01-15T13:45:00Z o 2025-01-15T13:45:00+02:00.
  • Tratta i valori solo-data come dati, non come un momento nel tempo. Se è un compleanno o una scadenza, tienilo come stringa semplice ("YYYY-MM-DD") ed evita di convertirlo in Date a meno che non definisci anche il fuso orario intenzionato.

Per input utente:

  • Non accettare formati ambigui come 03/04/2025 a meno che la UI non imponga il significato.
  • Preferisci input controllati (date picker) che producono un formato noto.
  • Se devi parsare testo libero, definisci e applica i formati accettati in anticipo.

Usa regole esplicite (non euristiche)

Invece di affidarti a Date.parse() per “capirlo”, scegli uno di questi approcci:

  • Accetta solo ISO 8601 dai server; rifiuta qualsiasi altra cosa.
  • Analizza manualmente formati noti (split della stringa e new Date(year, monthIndex, day) per date locali).
  • Memorizza e trasmetti timestamp (epoch milliseconds) per istanti precisi e formatta per la visualizzazione più tardi.

Quando i dati temporali sono critici, “parse funziona sulla mia macchina” non basta — rendi le regole di parsing esplicite e coerenti.

Formattare per gli utenti con Intl.DateTimeFormat

Se il tuo obiettivo è “mostrare una data/ora nel modo che le persone si aspettano”, lo strumento migliore in JavaScript è Intl.DateTimeFormat. Usa le regole di locale dell'utente (ordine, separatori, nomi dei mesi) ed evita l'approccio fragile di costruire manualmente stringhe come month + '/' + day.

Perché è meglio che costruire stringhe manualmente

La formattazione manuale spesso fissa l'output in stile USA, dimentica gli zeri iniziali o produce risultati 24/12 ore confusi. Intl.DateTimeFormat rende anche esplicito quale fuso orario stai mostrando—critico quando i dati sono memorizzati in UTC ma la UI deve riflettere l'ora locale dell'utente.

Opzioni comuni che userai davvero

Per “formatta semplicemente”, dateStyle e timeStyle sono i più semplici:

const d = new Date('2025-01-05T16:30:00Z');

// User’s locale + user’s local time zone
console.log(new Intl.DateTimeFormat(undefined, {
  dateStyle: 'medium',
  timeStyle: 'short'
}).format(d));

// Force a specific time zone (great for event times)
console.log(new Intl.DateTimeFormat('en-GB', {
  dateStyle: 'full',
  timeStyle: 'short',
  timeZone: 'UTC'
}).format(d));

Se hai bisogno di un ciclo orario consistente (es. un toggle nelle impostazioni), usa hour12:

console.log(new Intl.DateTimeFormat('en-US', {
  hour: 'numeric',
  minute: '2-digit',
  hour12: true
}).format(d));

Un pattern pratico per la UI

Scegli una funzione di formattazione per ogni “tipo” di timestamp nella UI (ora del messaggio, voce di log, inizio evento) e mantieni la decisione sul timeZone intenzionale:

  • Usa l'ora locale per “quando è successo per me”.
  • Usa un fuso fisso (spesso UTC) per audit log, eventi server o coordinazione tra team.

Questo ti dà un output coerente e amichevole per la locale senza dover mantenere una serie fragile di stringhe di formato personalizzate.

Ora legale: il bug nascosto dello spostamento di un'ora

Get rewarded for sharing builds
Condividi ciò che crei e guadagna crediti tramite contenuti e referral.
Guadagna crediti

L'ora legale (DST) è quando un fuso orario cambia il suo offset UTC (tipicamente di un'ora) in date specifiche. La parte difficoltosa: il DST non cambia solo l'offset—cambia l'esistenza di certe ore locali.

Orari locali mancanti e duplicati

Quando l'orologio avanza (spring forward), un intervallo di ore locali non esiste. Per esempio, in molte regioni l'orologio salta da 01:59 a 03:00, quindi le 02:30 locali sono “invisibili”.

Quando l'orologio torna indietro (fall back), un intervallo di ore locali accade due volte. Per esempio, 01:30 può verificarsi una volta prima del cambio e una dopo, il che significa che la stessa ora sul quadrante può riferirsi a due istanti diversi.

Aggiungere 24 ore vs “stessa ora locale domani”

Queste due cose non sono equivalenti attorno ai confini DST:

  • Aggiungi 24 ore: “esattamente 24 * 60 * 60 secondi dopo”
  • Il giorno dopo alla stessa ora locale: “domani alle 9:00 in questo fuso orario”

Se stanotte entra in vigore l'ora legale, “domani alle 9:00” potrebbe essere a 23 ore di distanza. Se stanotte l'ora termina, potrebbe essere a 25 ore di distanza.

// Scenario: schedule “same local time tomorrow”
const d = new Date(2025, 2, 8, 9, 0); // Mar 8, 9:00 local

const plus24h = new Date(d.getTime() + 24 * 60 * 60 * 1000);
const nextDaySameLocal = new Date(d);
nextDaySameLocal.setDate(d.getDate() + 1);

// Around DST, plus24h and nextDaySameLocal can differ by 1 hour.

Perché setHours può sorprenderti

Se fai qualcosa come date.setHours(2, 30, 0, 0) in un giorno di “spring forward”, JavaScript può normalizzarlo a un'ora valida diversa (spesso 03:30), perché le 02:30 non esistono in locale.

Approcci più sicuri

  • Esegui i calcoli in UTC per durate: usa epoch milliseconds e metodi UTC.
  • Per scheduling locale, sii esplicito sull'intento: “domani alle 9:00 locale” dovrebbe usare operazioni di calendario (setDate) invece di aggiungere millisecondi.
  • Quando scambi orari via API, preferisci ISO 8601 con offset o Z così l'istante è inequivocabile.

Durate vs Date: non usare Date per un timer

Una fonte comune di bug è usare Date per rappresentare qualcosa che non è un momento sul calendario.

Un timestamp risponde a “quando è successo?” (un istante specifico come 2025-12-23T10:00:00Z). Una durata risponde a “per quanto tempo?” (come “3 minuti 12 secondi”). Sono concetti diversi, e mescolarli porta a calcoli confusi ed effetti indesiderati legati a fuso orario/DST.

Perché Date è lo strumento sbagliato per durate

Date rappresenta sempre un punto sulla linea temporale relativo a un epoch. Se memorizzi “90 secondi” come Date, stai davvero memorizzando “1970-01-01 più 90 secondi” in un fuso orario. Formattandolo potresti vedere 01:01:30, subire uno spostamento di un'ora o mostrare una data che non volevi.

Per le durate, preferisci numeri semplici:

  • Memorizza durate in secondi o millisecondi (scegli un'unità e mantienila).
  • Esegui l'aritmetica con numeri.
  • Converti in stringa di visualizzazione solo alla fine.

Convertire secondi in HH:mm:ss

Ecco un semplice formatter che funziona per timer e lunghezze multimediali:

function formatHMS(totalSeconds) {
  const s = Math.max(0, Math.floor(totalSeconds));
  const hh = String(Math.floor(s / 3600)).padStart(2, "0");
  const mm = String(Math.floor((s % 3600) / 60)).padStart(2, "0");
  const ss = String(s % 60).padStart(2, "0");
  return `${hh}:${mm}:${ss}`;
}

formatHMS(75);    // "00:01:15" (countdown timer)
formatHMS(5423);  // "01:30:23" (media duration)

Se devi convertire da minuti, moltiplica prima (minutes * 60) e mantieni il valore numerico fino al rendering.

Confronti, ordinamenti e range senza sorprese

Quando confronti orari in JavaScript, l'approccio più sicuro è confrontare numeri, non testo formattato. Un oggetto Date è essenzialmente un wrapper attorno a un timestamp numerico (epoch milliseconds), quindi vuoi che i confronti finiscano come “numero vs numero”.

Confronti sicuri (i timestamp vincono)

Usa getTime() (o Date.valueOf(), che restituisce lo stesso numero) per confrontare in modo affidabile:

const a = new Date('2025-01-10T12:00:00Z');
const b = new Date('2025-01-10T12:00:01Z');

if (a.getTime() < b.getTime()) {
  // a is earlier
}

// Also works:
if (+a < +b) {
  // unary + calls valueOf()
}

Evita di confrontare stringhe formattate come "1/10/2025, 12:00 PM"—quelle dipendono dalla locale e non si ordineranno correttamente. L'eccezione principale sono le stringhe ISO 8601 nello stesso formato e fuso orario (es. tutte ...Z), che sono ordinabili lessicograficamente.

Ordinamento e filtro per intervallo

Ordinare per tempo è semplice se ordini per epoch milliseconds:

items.sort((x, y) => new Date(x.createdAt).getTime() - new Date(y.createdAt).getTime());

Filtrare elementi entro un intervallo è la stessa idea:

const start = new Date('2025-01-01T00:00:00Z').getTime();
const end   = new Date('2025-02-01T00:00:00Z').getTime();

const inRange = items.filter(i => {
  const t = new Date(i.createdAt).getTime();
  return t >= start && t < end;
});

“Inizio/fine della giornata” (locale vs UTC)

“Start of day” dipende se intendi ora locale o UTC:

// Local start/end of day
const d = new Date(2025, 0, 10); // Jan 10 in local time
const localStart = new Date(d.getFullYear(), d.getMonth(), d.getDate(), 0, 0, 0, 0);
const localEnd   = new Date(d.getFullYear(), d.getMonth(), d.getDate(), 23, 59, 59, 999);

// UTC start/end of day
const utcStart = new Date(Date.UTC(2025, 0, 10, 0, 0, 0, 0));
const utcEnd   = new Date(Date.UTC(2025, 0, 10, 23, 59, 59, 999));

Scegli una definizione presto e mantienila nelle tue logiche di confronto e range.

Checklist di debug: come diagnosticare un bug di conversione temporale

Build a mobile scheduling UI
Crea una schermata di scheduling in Flutter che mostri orari locali con fusi espliciti.
Crea mobile

I bug temporali sembrano casuali finché non individui cosa hai (timestamp? stringa? Date?) e dove si introduce lo scostamento (parsing, conversione di fuso, formattazione).

1) Cattura le “tre viste” dello stesso momento

Inizia loggando lo stesso valore in tre modi diversi. Questo rivela velocemente se il problema è secondi vs millisecondi, locale vs UTC o parsing di stringhe.

console.log('raw input:', input);

const d = new Date(input);
console.log('toISOString (UTC):', d.toISOString());
console.log('toString (local):', d.toString());
console.log('timezone offset (min):', d.getTimezoneOffset());

Cosa cercare:

  • Se toISOString() è completamente sbagliato (es. anno 1970 o un futuro lontano), sospetta secondi vs millisecondi.
  • Se toISOString() sembra giusto ma toString() è “spostato”, stai vedendo un problema di visualizzazione nel fuso locale.
  • Se getTimezoneOffset() cambia a seconda della data, stai attraversando l'ora legale.

2) Verifica l'ambiente: fuso orario e locale

Molti “funziona sulla mia macchina” sono semplicemente default ambientali diversi.

  • Browser: controlla le impostazioni del fuso orario del sistema operativo e la lingua del browser. Poi logga:
console.log(Intl.DateTimeFormat().resolvedOptions());
  • Node.js / server: conferma il fuso orario del processo:
console.log('TZ:', process.env.TZ);
console.log(Intl.DateTimeFormat().resolvedOptions().timeZone);

Se il server gira in UTC ma il tuo portatile in un fuso locale, l'output formattato differirà a meno che non specifichi esplicitamente un timeZone.

3) Aggiungi test dove il tempo si rompe più spesso

Crea test unitari attorno ai boundary DST e agli orari “edge”:

  • Un'ora prima e dopo lo switch DST nella zona rilevante
  • Fine mese/anno, e crossover 23:30 → 00:30
  • Più fusi orari se il tuo prodotto li supporta

Se iteri velocemente, considera di rendere questi test parte del tuo scaffolding. Per esempio, quando generi una app React + Go con Koder.ai, puoi aggiungere una piccola suite di “time contract” all'inizio (esempi di payload API + asserzioni di parsing/formattazione) così le regressioni vengono intercettate prima del deploy.

Checklist rapida prima del rilascio

  • Gli input hanno un contratto chiaro: epoch milliseconds o ISO 8601 con offset.
  • Nessuna stringa ambigua come "2025-03-02 10:00".
  • La formattazione specifica sempre locale e (quando serve) timeZone.
  • I test coprono i confini DST per le regioni target.

Pattern raccomandati per una gestione affidabile del tempo

La gestione affidabile del tempo in JavaScript è per lo più scegliere una “fonte di verità” e mantenere coerenza da storage a display.

Un semplice insieme di best practice

Memorizza e calcola in UTC. Tratta l'ora locale dell'utente come un dettaglio di presentazione.

Trasmetti date tra sistemi come stringhe ISO 8601 con offset esplicito (preferibilmente Z). Se devi inviare epoch numerici, documenta l'unità e mantienila coerente (millisecondi è il default comune in JS).

Formatta per gli utenti con Intl.DateTimeFormat (o toLocaleString) e passa un timeZone esplicito quando vuoi output deterministico (per esempio, mostrare sempre orari in UTC o in una regione business specifica).

Guida decisionale: DB vs API vs UI

  • Database: memorizza un istante in UTC (epoch milliseconds o un tipo datetime UTC). Evita datetime “locali” a meno che il dominio non richieda orari sul quadrante (es. “negozio apre alle 09:00”).
  • API boundaries: preferisci ISO 8601 con Z (es. 2025-12-23T10:15:00Z). Se usi epoch, includi un nome campo come createdAtMs per chiarire le unità.
  • UI: prendi l'istante UTC memorizzato e formatta per la locale dell'utente. Per interfacce di scheduling, etichetta chiaramente il fuso orario e mantieni le conversioni esplicite.

Quando vale la pena usare una libreria

Considera una libreria dedicata se ti servono eventi ricorrenti, regole complesse sui fusi orari, aritmetica sicura rispetto a DST (“stessa ora locale domani”) o molto parsing da input incoerenti. Il valore sta nelle API più chiare e in meno bug di edge-case.

Se vuoi approfondire, consulta le guide nel blog. Se stai valutando strumenti o opzioni di supporto, consulta la pagina dei prezzi.

Indice
Cosa va storto di solito con il tempo in JavaScriptTipi di dati temporali: Timestamp, Date e StringaTimestamp: secondi vs millisecondi (facile confonderli)Ora locale vs UTC: perché l'output si spostaStringhe ISO 8601: il formato più sicuro per le APITrappole del parsing: Date.parse e differenze tra browserFormattare per gli utenti con Intl.DateTimeFormatOra legale: il bug nascosto dello spostamento di un'oraDurate vs Date: non usare Date per un timerConfronti, ordinamenti e range senza sorpreseChecklist di debug: come diagnosticare un bug di conversione temporalePattern raccomandati per una gestione affidabile del tempo
Condividi
Koder.ai
Build your own app with Koder today!

The best way to understand the power of Koder is to see it for yourself.

Start FreeBook a Demo