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.
| Data | Settimana ISO | Settimana US (inizio dom) |
|---|---|---|
| 28 dicembre 2025 | Settimana 52, 2025 | Settimana 53, 2025 |
| 29 dicembre 2025 | Settimana 1, 2026 | Settimana 53, 2025 |
| 30 dicembre 2025 | Settimana 1, 2026 | Settimana 53, 2025 |
| 31 dicembre 2025 | Settimana 1, 2026 | Settimana 53, 2025 |
| 1 gennaio 2026 | Settimana 1, 2026 | Settimana 1, 2026 |
| 2 gennaio 2026 | Settimana 1, 2026 | Settimana 1, 2026 |
| 3 gennaio 2026 | Settimana 1, 2026 | Settimana 1, 2026 |
| 4 gennaio 2026 | Settimana 1, 2026 | Settimana 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_ritorno | La settimana inizia di |
|---|---|
| 1 (default) | Domenica |
| 2 | Lunedì |
| 11 | Lunedì |
| 12 | Martedì |
| 13 | Mercoledì |
| 14 | Giovedì |
| 15 | Venerdì |
| 16 | Sabato |
| 17 | Domenica |
| 21 | Lunedì (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
| Strumento | Settimana ISO | Settimana US | Note |
|---|---|---|---|
| Excel | ISOWEEKNUM() o WEEKNUM(d, 21) | WEEKNUM() default | ISOWEEKNUM aggiunta nel 2013 |
| Google Sheets | ISOWEEKNUM() | WEEKNUM() default | Uguale a Excel |
| Python | date.isocalendar()[1] o %V | %W (lun) / %U (dom) | Usa %G per l'anno della settimana ISO |
| JavaScript | Manuale o date-fns getISOWeek() | Manuale | Nessun numero di settimana nativo |
| PostgreSQL | EXTRACT(week ...) | Non built-in | ISO per default |
| MySQL | WEEK(d, 3) | WEEK(d) o WEEK(d, 0) | Modalità 3 = ISO |
| SQL Server | DATEPART(isowk, d) | DATEPART(week, d) | Default è US |
| SQLite | Workaround richiesto | strftime('%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.
