Cum convertești un număr de săptămână într-un interval de date — ghid complet

Cineva îți trimite un program. „Livrare în W23.” Deschizi calendarul și te uiți la el. Ce date înseamnă asta, mai exact?

Numerele de săptămână se folosesc peste tot în planificarea proiectelor, producție, retail și logistică — dar majoritatea le știu doar ca etichete. Să convertești un număr de săptămână înapoi în datele reale din calendar e mai puțin intuitiv decât ar trebui, iar cazurile de la granița anilor îi încurcă chiar și pe dezvoltatorii cu experiență.

Ghidul acesta acoperă conversia completă: număr de săptămână → luni, număr de săptămână → interval complet (luni–duminică) și invers (dată → număr de săptămână). Include cod pentru Python, JavaScript, Excel și SQL.

Ce îți spune de fapt un număr de săptămână

Înainte să calculezi ceva, trebuie să știi din ce sistem de numerotare a săptămânilor provine numărul.

ISO 8601 (standardul internațional): Săptămâna 1 este săptămâna care conține prima zi de joi din an. Săptămânile sunt de luni până duminică. Un an are 52 sau 53 de săptămâni ISO. Important — anul de săptămână ISO poate fi diferit de anul calendaristic. Ultimele zile din decembrie pot fi uneori în Săptămâna 1 a anului următor.

Stil SUA: Săptămâna 1 conține 1 ianuarie. Săptămânile pot fi duminică–sâmbătă sau luni–duminică, în funcție de instrument. 1 ianuarie este întotdeauna în săptămâna 1, fără excepții.

În restul acestui ghid, „număr de săptămână” înseamnă ISO 8601, dacă nu se precizează altfel. Dacă cineva ți-a dat un număr de săptămână dintr-un instrument „US-based” (de exemplu, Excel implicit cu WEEKNUM), formula de conversie este diferită — vezi secțiunea de mai jos.

Ai nevoie și de an. „Săptămâna 23” nu înseamnă nimic fără an. Tratează întotdeauna numerele de săptămână ca perechea (an, săptămână). Săptămâna 23 din 2025 începe pe 2 iunie. Săptămâna 23 din 2026 începe pe 1 iunie. Săptămâna 1 din 2026 începe pe 29 decembrie din 2025.

Formula de bază: număr de săptămână ISO → luni

Fiecare săptămână ISO începe într-o zi de luni. Ca să găsești lunea din săptămâna ISO W a anului Y:

Monday = Jan 4 of Y + (W - 1) × 7 days - weekday(Jan 4 of Y) + 1

Raționamentul: 4 ianuarie este întotdeauna în Săptămâna ISO 1 (prin definiție — e în primele patru zile ale anului, ceea ce garantează că săptămâna include o zi de joi). Găsești lunea săptămânii care conține 4 ianuarie, apoi avansezi cu (W - 1) săptămâni.

O variantă echivalentă, mai curată:

Monday of W1 = Jan 4 of Y - weekday(Jan 4 of Y) + 1
Monday of W  = Monday of W1 + (W - 1) × 7

unde weekday întoarce 1 pentru luni până la 7 pentru duminică (numerotare ISO a zilelor săptămânii).

Exemplu: săptămâna 23 din 2026

  • 4 ianuarie 2026 este duminică. Zi ISO = 7.
  • Lunea din W1: 4 ian − 7 + 1 = 29 decembrie 2025.
  • Lunea din W23: 29 decembrie 2025 + 22 × 7 = 29 dec + 154 zile = 1 iunie 2026.
  • Duminica din W23: 1 iunie + 6 = 7 iunie 2026.

Săptămâna 23 din 2026 este între 1 iunie (luni) și 7 iunie (duminică).

Capcana de la trecerea dintre ani

Cea mai frecventă greșeală: să presupui că Săptămâna 1 din anul Y începe întotdeauna în anul Y.

Nu începe.

Săptămâna 1 dintr-un an este săptămâna care conține prima zi de joi. Dacă acea joi cade la început de ianuarie, lunea din Săptămâna 1 poate fi în decembrie anul anterior.

Exemple:

Săptămâna ISOAnLuniDuminică
W1202530 decembrie 20245 ianuarie 2025
W1202629 decembrie 20254 ianuarie 2026
W120274 ianuarie 202710 ianuarie 2027
W120283 ianuarie 20289 ianuarie 2028

W1 din 2025 începe în decembrie 2024. W1 din 2026 începe în decembrie 2025.

Asta înseamnă:

  • 29–31 decembrie 2025 sunt în Săptămâna ISO 1 din 2026, nu din 2025.
  • Dacă cineva spune „livrare până în W1 2026”, termenul-limită e săptămâna care începe pe 29 decembrie 2025.

Există și capcana inversă: ultimele zile din unii ani cad în Săptămâna 1 a anului următor, nu în ultima săptămână a anului curent. Folosește întotdeauna anul de săptămână ISO (codul de format %G în Python, isoyear în PostgreSQL) când etichetezi o săptămână — nu anul calendaristic.

Intervalul complet de date pentru orice săptămână

După ce ai lunea, restul săptămânii e simplu:

ZiDiferență față de luni
Luni+0
Marți+1
Miercuri+2
Joi+3
Vineri+4
Sâmbătă+5
Duminică+6

Intervalul pentru săptămâna W este: [luni, luni + 6 zile].

Pentru zile lucrătoare (doar luni–vineri): [luni, luni + 4 zile].

Python

from datetime import date, timedelta

def iso_week_to_monday(year: int, week: int) -> date:
    # Jan 4 is always in ISO week 1
    jan4 = date(year, 1, 4)
    # Move back to Monday of that week
    week1_monday = jan4 - timedelta(days=jan4.weekday())
    # Step forward to the target week
    return week1_monday + timedelta(weeks=week - 1)

def iso_week_to_range(year: int, week: int) -> tuple[date, date]:
    monday = iso_week_to_monday(year, week)
    sunday = monday + timedelta(days=6)
    return monday, sunday

# Examples
monday, sunday = iso_week_to_range(2026, 23)
print(monday)   # 2026-06-01
print(sunday)   # 2026-06-07

monday, sunday = iso_week_to_range(2026, 1)
print(monday)   # 2025-12-29  ← note: starts in 2025
print(sunday)   # 2026-01-04

Python are și o funcție încorporată pentru invers (dată → săptămână ISO):

d = date(2026, 6, 4)
iso_year, iso_week, iso_weekday = d.isocalendar()
print(iso_year, iso_week)  # 2026 23

Folosește d.isocalendar().year (nu d.year) când ai nevoie de anul ISO — ele diferă la granița anilor.

Pentru căutarea inversă cu fromisocalendar (Python 3.8+):

# Get Monday of ISO week 23, 2026 directly
monday = date.fromisocalendar(2026, 23, 1)  # weekday 1 = Monday
print(monday)  # 2026-06-01

date.fromisocalendar(year, week, weekday) este cea mai curată abordare dacă folosești Python 3.8 sau mai nou.

JavaScript

JavaScript nu are suport nativ pentru săptămâni ISO. Implementare manuală:

function isoWeekToMonday(year, week) {
  // Jan 4 is always in ISO week 1
  const jan4 = new Date(year, 0, 4)
  const dayOfWeek = jan4.getDay() || 7  // convert Sun=0 to 7
  const week1Monday = new Date(jan4)
  week1Monday.setDate(jan4.getDate() - dayOfWeek + 1)
  
  const monday = new Date(week1Monday)
  monday.setDate(week1Monday.getDate() + (week - 1) * 7)
  return monday
}

function isoWeekToRange(year, week) {
  const monday = isoWeekToMonday(year, week)
  const sunday = new Date(monday)
  sunday.setDate(monday.getDate() + 6)
  return { monday, sunday }
}

// Examples
const { monday, sunday } = isoWeekToRange(2026, 23)
console.log(monday.toISOString().slice(0, 10))  // 2026-06-01
console.log(sunday.toISOString().slice(0, 10))  // 2026-06-07

const w1 = isoWeekToRange(2026, 1)
console.log(w1.monday.toISOString().slice(0, 10))  // 2025-12-29

Folosind date-fns:

import { setISOWeek, setISOWeekYear, startOfISOWeek, endOfISOWeek } from 'date-fns'

function isoWeekToRange(year, week) {
  let d = new Date(year, 0, 4)  // any date in the target year
  d = setISOWeekYear(d, year)
  d = setISOWeek(d, week)
  return {
    monday: startOfISOWeek(d),
    sunday: endOfISOWeek(d)
  }
}

date-fns gestionează corect toate cazurile limită și este abordarea recomandată pentru cod de producție.

Excel și Google Sheets

Excel nu are o funcție directă „număr de săptămână → dată”, dar o poți construi cu o formulă.

Lunea din săptămâna ISO W în anul Y:

=DATE(Y,1,4) - WEEKDAY(DATE(Y,1,4),2) + 1 + (W-1)*7

Pe scurt:

  • DATE(Y,1,4) — 4 ianuarie al anului
  • WEEKDAY(DATE(Y,1,4),2) — ziua săptămânii unde luni=1, duminică=7
  • Scăzând obții lunea din Săptămâna 1
  • Adăugând (W-1)*7 ajungi la săptămâna dorită

Pentru interval complet, duminica este:

=Monday_formula + 6

Exemplu într-un tabel (unde A1 = an, B1 = număr de săptămână):

Monday: =DATE(A1,1,4) - WEEKDAY(DATE(A1,1,4),2) + 1 + (B1-1)*7
Sunday: =Monday_cell + 6

Formatează ambele celule ca date. Pentru anul 2026, săptămâna 1, formula întoarce 29 decembrie 2025 pentru luni — ceea ce este corect.

Invers (dată → număr de săptămână ISO): folosește ISOWEEKNUM(date). Pentru anul ISO, folosește soluția alternativă din articolul despre ISOWEEKNUM, deoarece Excel nu are o funcție nativă pentru anul ISO.

SQL

PostgreSQL are cel mai complet suport ISO:

-- Monday of ISO week W in year Y
SELECT
  make_date(2026, 1, 4)
    + (23 - 1) * 7  -- step to week 23
    - EXTRACT(isodow FROM make_date(2026, 1, 4))::int + 1
    AS week_monday;
-- 2026-06-01

-- Or more cleanly using generate_series for a range lookup
SELECT
  d::date AS week_monday,
  (d + 6)::date AS week_sunday,
  EXTRACT(isoyear FROM d) AS iso_year,
  EXTRACT(week FROM d) AS iso_week
FROM generate_series(
  DATE '2026-01-01',
  DATE '2026-12-31',
  INTERVAL '7 days'
) d
WHERE EXTRACT(week FROM d) = 23
  AND EXTRACT(isoyear FROM d) = 2026;

O abordare mai curată, folosind to_date din PostgreSQL cu coduri de format ISO:

-- Convert ISO year + week to Monday
SELECT to_date('2026' || '23' || '1', 'IYYYIWid') AS monday;
-- 2026-06-01

-- Format: IYYY=ISO year, IW=ISO week, id=ISO day (1=Monday)

Aceasta este cea mai simplă abordare în PostgreSQL: formezi un șir YYYYWWD și îl parsezi cu coduri de format ISO.

MySQL:

-- Monday of ISO week 23, 2026
SELECT STR_TO_DATE('202623 Monday', '%X%V %W');
-- 2026-06-01

-- Or step-based:
SELECT DATE_ADD(
  DATE_ADD(STR_TO_DATE('2026-01-04', '%Y-%m-%d'),
    INTERVAL (-(WEEKDAY(STR_TO_DATE('2026-01-04', '%Y-%m-%d')))) DAY),
  INTERVAL (23 - 1) * 7 DAY
) AS week_monday;

SQL Server:

-- Monday of ISO week 23, 2026
DECLARE @year INT = 2026, @week INT = 23

SELECT DATEADD(
  DAY,
  (@week - 1) * 7
    - (DATEPART(WEEKDAY, DATEFROMPARTS(@year, 1, 4)) + 5) % 7,
  DATEFROMPARTS(@year, 1, 4)
) AS week_monday;
-- 2026-06-01

Număr de săptămână „stil SUA” → date

Dacă numărul tău de săptămână vine dintr-un sistem „stil SUA” (Săptămâna 1 = conține 1 ianuarie, săptămânile încep duminică sau luni), formula este mai simplă pentru că nu există problema graniței de an:

Începutul săptămânii (duminică):

Week_start = DATE(Y, 1, 1) + (W - 1) × 7 - WEEKDAY(DATE(Y, 1, 1), 1)

unde WEEKDAY întoarce 1 pentru duminică până la 7 pentru sâmbătă.

Dar numerele de săptămână în stil SUA sunt mult mai rare în planificare și logistică decât ISO. Dacă cineva îți dă un număr de săptămână fără să precizeze sistemul, presupune ISO — mai ales în contexte internaționale sau în Europa.

Referință rapidă 2026: săptămânile ISO 1–10 și 48–53

Săptămâna ISOAnLuniDuminică
W1202629 decembrie 20254 ianuarie 2026
W220265 ianuarie 202611 ianuarie 2026
W3202612 ianuarie 202618 ianuarie 2026
W4202619 ianuarie 202625 ianuarie 2026
W5202626 ianuarie 20261 februarie 2026
W620262 februarie 20268 februarie 2026
W720269 februarie 202615 februarie 2026
W8202616 februarie 202622 februarie 2026
W9202623 februarie 20261 martie 2026
W1020262 martie 20268 martie 2026
...
W48202623 noiembrie 202629 noiembrie 2026
W49202630 noiembrie 20266 decembrie 2026
W5020267 decembrie 202613 decembrie 2026
W51202614 decembrie 202620 decembrie 2026
W52202621 decembrie 202627 decembrie 2026
W53202628 decembrie 20263 ianuarie 2027

Observă că W1 din 2026 începe pe 29 decembrie 2025. Observă că W53 din 2026 se termină pe 3 ianuarie 2027 — 2026 este un an cu 53 de săptămâni.

Greșeli frecvente (rezumat)

Să nu incluzi anul. „Săptămâna 8” e ambiguă. Folosește formatul 2026-W08 sau echivalent.

Să folosești anul calendaristic în loc de anul ISO al săptămânii. 29 decembrie 2025 este în Săptămâna ISO 1 din 2026, nu din 2025. Dacă o stochezi sub 2025, o pui în categoria greșită.

Să presupui că Săptămâna 1 începe pe 1 ianuarie. În mulți ani începe pe 29, 30 sau 31 decembrie. Dacă ai nevoie ca 1 ianuarie să fie mereu în Săptămâna 1, folosești sistemul SUA, nu ISO.

Eroare „off-by-one” în formula pentru luni. Ancora de Jan 4 este importantă — nu 1 ianuarie (care poate fi în ultima săptămână a anului anterior). Dacă folosești 1 ianuarie ca ancoră, obții rezultate greșite în anii în care 1 ianuarie cade târziu în săptămână.

Să nu testezi datele de la granița anilor. Orice cod care lucrează cu date ar trebui testat pentru 28–31 decembrie și 1–4 ianuarie. În aceste 4–7 zile apar toate cazurile limită.

Folosește Calculatorul de număr de săptămână ISO ca să vezi intervalul pentru orice săptămână sau verifică numărul săptămânii curente și intervalul ISO al zilei de azi.