Perché Excel, SQL, Python e JavaScript Assegnano Numeri di Settimana Diversi Alla Stessa Data

Calcoli un numero di settimana in Python, poi apri la stessa data in Excel, e i numeri non corrispondono. Esegui una query SQL e ottieni un terzo risultato. Cerchi online e ne trovi un quarto.

Non è un bug. È una scelta progettuale che ogni strumento fa diversamente — e la maggior parte non la documenta abbastanza bene.

Ci sono almeno due sistemi principali di numerazione delle settimane in uso comune, diverse variazioni all'interno di ogni sistema, e nessun default universale. Una volta compresi i dettagli, debuggare i disallineamenti è questione di secondi. Prima di allora, sono frustranti.

I Due Sistemi Principali

ISO 8601 (usato nella maggior parte dell'Europa, negli affari internazionali e nei contesti scientifici)

  • Le settimane vanno da lunedì a domenica
  • La settimana 1 è quella che contiene il primo giovedì dell'anno
  • Un anno ha 52 o 53 settimane
  • L'anno della settimana può differire dall'anno di calendario ai confini

Sistema americano / semplice (usato in Nord America e molti default dei fogli di calcolo)

  • Le settimane vanno da domenica a sabato (o a volte da lunedì a domenica, a seconda della locale)
  • La settimana 1 è quella che contiene il 1° gennaio
  • Il 1° gennaio è sempre nella settimana 1, indipendentemente da quale giorno cada
  • Le settimane parziali a fine anno ottengono numeri alti (52 o 53), non vengono riassegnate all'anno successivo

La differenza pratica si vede più chiaramente a fine dicembre e inizio gennaio.

DataSettimana ISOSettimana US (inizio dom)
28 dicembre 2025Settimana 52, 2025Settimana 53, 2025
29 dicembre 2025Settimana 1, 2026Settimana 53, 2025
30 dicembre 2025Settimana 1, 2026Settimana 53, 2025
31 dicembre 2025Settimana 1, 2026Settimana 53, 2025
1 gennaio 2026Settimana 1, 2026Settimana 1, 2026
2 gennaio 2026Settimana 1, 2026Settimana 1, 2026
3 gennaio 2026Settimana 1, 2026Settimana 1, 2026
4 gennaio 2026Settimana 1, 2026Settimana 2, 2026

Il 29–31 dicembre 2025 rientra nella settimana ISO 1 del 2026 — perché il giovedì di quella settimana (1° gennaio) è nel 2026. Il sistema US li mantiene nella settimana 53 del 2025.

Excel: WEEKNUM vs ISOWEEKNUM

Excel ha due funzioni separate, il che è più chiaro della maggior parte degli strumenti.

WEEKNUM(data, [tipo_ritorno]) — stile US, con inizio della settimana configurabile

L'argomento tipo_ritorno controlla quale giorno inizia la settimana:

tipo_ritornoLa settimana inizia di
1 (default)Domenica
2Lunedì
11Lunedì
12Martedì
13Mercoledì
14Giovedì
15Venerdì
16Sabato
17Domenica
21Lunedì (ISO 8601)

tipo_ritorno = 21 fa sì che WEEKNUM si comporti come ISO — ma questo è documentato male e la maggior parte degli utenti non sa che esiste.

ISOWEEKNUM(data) — ISO 8601, sempre inizio lunedì, regola del giovedì

È stata aggiunta in Excel 2013. Restituisce il numero di settimana ISO corretto ed è univoca.

=ISOWEEKNUM("2025-12-31")   → 1    (settimana 1 del 2026)
=WEEKNUM("2025-12-31", 1)   → 53   (settimana 53 del 2025, inizio domenica)
=WEEKNUM("2025-12-31", 2)   → 53   (settimana 53 del 2025, inizio lunedì)
=WEEKNUM("2025-12-31", 21)  → 1    (compatibile ISO, uguale a ISOWEEKNUM)

Errore comune: Usare WEEKNUM con argomenti default quando si confronta con un sistema basato su ISO. I numeri corrisponderanno per la maggior parte delle date ma divergeranno silenziosamente a fine anno.

Google Sheets: Stesse Funzioni, Stesse Avvertenze

Google Sheets ha sia WEEKNUM che ISOWEEKNUM con lo stesso comportamento di Excel. Il default di WEEKNUM è stile US, inizio domenica. ISOWEEKNUM è ISO 8601.

Una differenza: Google Sheets è più coerente nel restituire l'anno della settimana ISO quando usi ISOWEEKNUM insieme a YEAR. Se scrivi =YEAR("2025-12-31") ottieni 2025, ma la settimana ISO appartiene al 2026. Non c'è un'unica funzione built-in che restituisca l'anno della settimana ISO — devi calcolarlo:

=IF(ISOWEEKNUM(A1) > 50, IF(MONTH(A1) = 1, YEAR(A1) - 1, YEAR(A1)),
   IF(ISOWEEKNUM(A1) < 3, IF(MONTH(A1) = 12, YEAR(A1) + 1, YEAR(A1)),
   YEAR(A1)))

Questo è verboso. Se stai facendo lavoro serio con anno-settimana in Sheets, è spesso più pulito esportare in Python o SQL.

Python: isocalendar() È ISO, Ma strftime('%W') Non Lo È

Il modulo datetime di Python ti dà due approcci diversi.

date.isocalendar() — ISO 8601, restituisce (anno, settimana, giorno_della_settimana)

from datetime import date

d = date(2025, 12, 31)
d.isocalendar()
# IsoCalendarDate(year=2026, week=1, weekday=3)

Nota che l'anno restituito è l'anno della settimana ISO (2026), non l'anno di calendario (2025). Questo è corretto e importante — se devi etichettare la settimana, usa iso_year non d.year.

strftime('%W') e strftime('%U') — stile US, inizi di settimana diversi

d.strftime('%W')   # Numero settimana, lunedì come primo giorno della settimana → '52'
d.strftime('%U')   # Numero settimana, domenica come primo giorno della settimana → '52'
d.strftime('%V')   # Numero settimana ISO → '01'
d.strftime('%G')   # Anno della settimana ISO → '2026'

La combinazione %V / %G è ISO-corretta. Le direttive %W / %U sono stile US e disaccorderanno con ISO ai confini dell'anno.

Errore comune: Usare d.strftime('%W') per ottenere numeri di settimana quando i tuoi altri sistemi usano ISO. Concorderanno per 48+ settimane dell'anno, poi divergeranno silenziosamente a dicembre e gennaio.

# Sbagliato per il confronto ISO — il confine dell'anno non corrisponderà
week = int(d.strftime('%W'))

# Corretto per ISO
iso_year, iso_week, _ = d.isocalendar()

JavaScript: Nessun Built-In, Fai Da Te

L'oggetto Date di JavaScript non ha nessun metodo nativo per il numero di settimana. Date.getDay() restituisce da 0 (domenica) a 6 (sabato). Devi calcolarlo manualmente o usare una libreria come date-fns o dayjs.

Calcolo manuale della settimana ISO:

function isoWeek(date) {
  const d = new Date(date)
  d.setHours(0, 0, 0, 0)
  // Il giovedì della settimana corrente determina l'anno
  d.setDate(d.getDate() + 3 - (d.getDay() + 6) % 7)
  const jan4 = new Date(d.getFullYear(), 0, 4)
  return 1 + Math.round(((d - jan4) / 86400000 - 3 + (jan4.getDay() + 6) % 7) / 7)
}

function isoWeekYear(date) {
  const d = new Date(date)
  d.setDate(d.getDate() + 3 - (d.getDay() + 6) % 7)
  return d.getFullYear()
}

isoWeek(new Date('2025-12-31'))      // 1
isoWeekYear(new Date('2025-12-31'))  // 2026

Usando date-fns:

import { getISOWeek, getISOWeekYear } from 'date-fns'

getISOWeek(new Date('2025-12-31'))      // 1
getISOWeekYear(new Date('2025-12-31'))  // 2026

Errore comune: Scrivere un semplice calcolo Math.ceil(giorno_dell_anno / 7) e chiamarlo numero di settimana. Questo non dà né risultati ISO né US-standard — è un sistema completamente diverso (e sbagliato).

SQL: Dipende dal Database

Ogni database principale gestisce i numeri di settimana diversamente.

PostgreSQL — ISO per default

SELECT EXTRACT(week FROM DATE '2025-12-31');
-- Restituisce 1 (settimana ISO)

SELECT DATE_PART('week', DATE '2025-12-31');
-- Restituisce 1 (uguale, ISO)

-- Ottieni l'anno della settimana ISO
SELECT EXTRACT(isoyear FROM DATE '2025-12-31');
-- Restituisce 2026

Il EXTRACT(week ...) di PostgreSQL segue ISO 8601. L'anno della settimana è disponibile tramite isoyear.

MySQL / MariaDB — più modalità

-- Modalità 3 è ISO 8601 (inizio lunedì, settimana 1 contiene giovedì)
SELECT WEEK('2025-12-31', 3);   -- 1

-- Modalità 0 (default) è stile US, inizio domenica
SELECT WEEK('2025-12-31', 0);   -- 53
SELECT WEEK('2025-12-31');      -- 53 (modalità default 0)

-- YEARWEEK restituisce anno+settimana combinati
SELECT YEARWEEK('2025-12-31', 3);  -- 202601

L'argomento modalità in MySQL è critico e ha 8 opzioni (0–7). La modalità 3 è ISO. La default (modalità 0) è stile US. Questa è una fonte comune di bug quando si cambiano database backend.

SQL Server — non ISO per default

-- Il DATEPART(week, ...) default non è ISO
SELECT DATEPART(week, '2025-12-31');   -- 53

-- Settimana ISO: usa isowk o iso_week
SELECT DATEPART(isowk, '2025-12-31');  -- 1
SELECT DATEPART(iso_week, '2025-12-31');  -- 1 (uguale)

Il default DATEPART(week, ...) di SQL Server usa lo stile US. L'alias isowk è la versione ISO. Se stai costruendo report che si confrontano con sistemi europei, usa sempre isowk.

SQLite — nessuna funzione nativa di settimana

SQLite non ha WEEKNUM o EXTRACT(week ...). Usi strftime:

-- '%W' è inizio lunedì, stile US
SELECT strftime('%W', '2025-12-31');   -- 52

-- La settimana ISO richiede un workaround
SELECT (strftime('%j', date('2025-12-31', '-3 days', 'weekday 4')) - 1) / 7 + 1;
-- 1

Il workaround ISO trova il giovedì della settimana e conta da lì. È corretto ma non ovvio.

Un Foglio di Aiuto

StrumentoSettimana ISOSettimana USNote
ExcelISOWEEKNUM() o WEEKNUM(d, 21)WEEKNUM() defaultISOWEEKNUM aggiunta nel 2013
Google SheetsISOWEEKNUM()WEEKNUM() defaultUguale a Excel
Pythondate.isocalendar()[1] o %V%W (lun) / %U (dom)Usa %G per l'anno della settimana ISO
JavaScriptManuale o date-fns getISOWeek()ManualeNessun numero di settimana nativo
PostgreSQLEXTRACT(week ...)Non built-inISO per default
MySQLWEEK(d, 3)WEEK(d) o WEEK(d, 0)Modalità 3 = ISO
SQL ServerDATEPART(isowk, d)DATEPART(week, d)Default è US
SQLiteWorkaround richiestostrftime('%W', d)Nessun supporto nativo

Come Evitare Disallineamenti in Pratica

Scegli un sistema e applicalo ovunque. ISO è il default migliore per la maggior parte dei nuovi sistemi — è standardizzato internazionalmente e quello che la maggior parte delle librerie moderne implementa.

Archivia sempre l'anno della settimana ISO insieme al numero di settimana. La settimana 1 del 2026 e la settimana 1 del 2025 sono settimane diverse. Una colonna che memorizza solo 1 è ambigua senza l'anno.

Controlla esplicitamente i casi ai confini dell'anno. Le date dal 28–31 dicembre e 1–3 gennaio sono dove si verificano i disallineamenti. Esegui la tua pipeline con date di test in questo intervallo prima di deployare.

In caso di dubbio, archivia e confronta date complete. I numeri di settimana sono per display e report, non per chiavi primarie o join. Se stai unendo dati tra sistemi su numero di settimana, converti prima a una data canonica (il lunedì della settimana).

Usa il Calcolatore del Numero di Settimana ISO per verificare il numero corretto della settimana ISO per qualsiasi data, inclusa la vista del calendario dell'anno completo.