Date și timp
Timestamp, UTC vs local, capcanele lui Date, calcule și formatare cu Intl.
Actualizat
Ce este un Date în JavaScript
Un obiect Date reprezintă un moment în timp — intern, doar un număr: milisecundele trecute de la 1 ianuarie 1970, ora 00:00 UTC (timestamp).
const now = new Date()
now.getTime() // 1791460800000 — timestamp-ul
Date.now() // același lucru, fără obiectTot ce vezi ca „8 octombrie, 14:30” e o interpretare a acelui număr într-un fus orar. Aici apar aproape toate bug-urile cu date.
UTC vs ora locală
| UTC | Ora locală | |
|---|---|---|
| Ce e | ora de referință universală, fără fus orar | ora din fusul orar al dispozitivului (România: UTC+2 iarna, UTC+3 vara) |
| Unde o folosești | stocare, API-uri, baze de date | doar la afișare |
| Metode | getUTCHours(), toISOString() |
getHours(), toLocaleString() |
Regula de aur: salvezi și transmiți în UTC (ISO 8601), afișezi în ora locală.
new Date().toISOString() // '2026-10-08T11:30:00.000Z' — Z = UTCCrearea unei date — capcanele
| Cod | Rezultat | Capcană |
|---|---|---|
new Date('2026-10-08') |
miezul nopții UTC | în România afișează 03:00 |
new Date('2026-10-08T10:00') |
ora locală | fără Z = local |
new Date('2026-10-08T10:00Z') |
ora UTC | explicit, sigur |
new Date(2026, 9, 8) |
8 octombrie | lunile încep de la 0 |
new Date('08/10/2026') |
depinde de browser | format ambiguu — nu-l folosi |
Calcule
const DAY = 24 * 60 * 60 * 1000
const diffDays = Math.round((b - a) / DAY) // scăderea a două Date dă milisecunde
const tomorrow = new Date(date)
tomorrow.setDate(tomorrow.getDate() + 1) // gestionează corect sfârșitul luniiAtenție: Date e mutabil — setDate modifică obiectul. Copiază înainte (new Date(date)).
Trecerea la ora de vară face ca o zi să aibă 23 sau 25 de ore — de aceea Math.round la diferența în zile.
Afișare cu Intl
new Intl.DateTimeFormat('ro-RO', { dateStyle: 'long' }).format(date) // '8 octombrie 2026'
new Intl.DateTimeFormat('ro-RO', { dateStyle: 'short', timeStyle: 'short' }).format(date)
new Intl.DateTimeFormat('ro-RO', { timeZone: 'Europe/London', timeStyle: 'short' }).format(date)
new Intl.RelativeTimeFormat('ro', { numeric: 'auto' }).format(-1, 'day') // 'ieri'
new Intl.RelativeTimeFormat('ro', { numeric: 'auto' }).format(3, 'day') // 'peste 3 zile'Date în Next.js — hidratare
O dată formatată pe server (fusul orar al serverului, de obicei UTC) și din nou pe client (fusul userului) poate da text diferit → eroare de hidratare. Soluții: formatezi cu un timeZone fix, sau afișezi ora relativă / locală doar în Client Component, după montare.
Librării și viitorul
| Variantă | Când |
|---|---|
Date + Intl |
majoritatea aplicațiilor |
| date-fns | multe calcule (adaugă luni, început de săptămână) — funcții mici, tree-shakable |
| Temporal (nativ, nou) | API modern, imutabil, cu fusuri orare corecte — înlocuitorul lui Date, disponibil progresiv în browsere |
Pe scurt
Date= timestamp UTC; tot restul e interpretare într-un fus orar.- Stochezi în UTC / ISO, afișezi local cu
Intl; lunile încep de la 0;Datee mutabil. - Atenție la hidratare în Next; date-fns pentru calcule, Temporal pentru viitor.