Kuinka muuntaa viikkonumero päivämääräväliksi — täydellinen opas
Joku lähettää sinulle aikataulun: ”Toimitus viikolla W23.” Avaat kalenterin ja tuijotat sitä. Mitkä päivät se tarkalleen tarkoittaa?
Viikkonumeroita käytetään kaikkialla projektisuunnittelussa, tuotannossa, vähittäiskaupassa ja logistiikassa — mutta useimmat tuntevat ne vain tunnisteina. Viikkonumeron muuttaminen takaisin kalenteripäiviksi on vähemmän intuitiivista kuin sen pitäisi olla, ja vuodenvaihteeseen liittyvät tapaukset hämäävät jopa kokeneita kehittäjiä.
Tässä oppaassa käydään läpi koko muunnos: viikkonumero → maanantai, viikkonumero → koko aikaväli (maanantai–sunnuntai) sekä käänteinen suunta (päivämäärä → viikkonumero). Mukana koodiesimerkit Pythonille, JavaScriptille, Excelille ja SQL:lle.
Mitä viikkonumero oikeasti kertoo
Ennen kuin lasket mitään, sinun on tiedettävä, mistä viikkonumerointijärjestelmästä numero on peräisin.
ISO 8601 (kansainvälinen standardi): Viikko 1 on se viikko, joka sisältää vuoden ensimmäisen torstain. Viikot ovat maanantaista sunnuntaihin. Vuodessa on 52 tai 53 ISO-viikkoa. Tärkeää: ISO-viikkovuosi voi poiketa kalenterivuodesta. Joulukuun viimeiset päivät ovat joskus seuraavan vuoden viikolla 1.
US-tyyli: Viikko 1 sisältää tammikuun 1. Viikko voi olla sunnuntaista lauantaihin tai maanantaista sunnuntaihin työkalusta riippuen. Tammikuun 1 on aina viikossa 1 — poikkeuksetta.
Tässä oppaassa ”viikkonumero” tarkoittaa ISO 8601 -järjestelmää, ellei toisin mainita. Jos viikkonumero tulee US-tyylisestä työkalusta (kuten Excelin oletus WEEKNUM), kaava on eri — katso oma osio alempaa.
Tarvitset myös vuoden. ”Viikko 23” on merkityksetön ilman vuotta. Käsittele viikkonumeroa aina parina (vuosi, viikko). Vuoden 2025 viikko 23 alkaa 2. kesäkuuta. Vuoden 2026 viikko 23 alkaa 1. kesäkuuta. Vuoden 2026 viikko 1 alkaa 29. joulukuuta vuonna 2025.
Peruskaava: ISO-viikkonumerosta maanantaihin
Jokainen ISO-viikko alkaa maanantaina. ISO-viikon W maanantai vuonna Y löytyy näin:
Maanantai = 4.1. Y + (W - 1) × 7 päivää - viikonpäivä(4.1. Y) + 1
Perustelu: 4. tammikuuta on aina ISO-viikolla 1 (määritelmän mukaan — se on vuoden neljän ensimmäisen päivän joukossa, mikä takaa, että viikko sisältää torstain). Etsi sen viikon maanantai ja siirry eteenpäin (W - 1) viikkoa.
Selkeämpi vastaava muoto:
Viikon 1 maanantai = 4.1. Y - viikonpäivä(4.1. Y) + 1
Viikon W maanantai = viikon 1 maanantai + (W - 1) × 7
missä viikonpäivä palauttaa 1 maanantaille … 7 sunnuntaille (ISO-viikonpäivän numerointi).
Esimerkki: viikko 23 vuonna 2026
- 4.1.2026 on sunnuntai. ISO-viikonpäivä = 7.
- Viikon 1 maanantai: 4.1. − 7 + 1 = 29.12.2025.
- Viikon 23 maanantai: 29.12.2025 + 22 × 7 = 29.12. + 154 päivää = 1.6.2026.
- Viikon 23 sunnuntai: 1.6. + 6 = 7.6.2026.
Vuoden 2026 viikko 23 kestää 1.6. (maanantai) – 7.6. (sunnuntai).
Vuodenvaihteen ansa
Yleisin virhe: olettaa, että vuoden Y viikko 1 alkaa aina vuonna Y.
Ei ala.
Viikko 1 on viikko, joka sisältää vuoden ensimmäisen torstain. Jos tuo torstai on tammikuun alussa, viikon 1 maanantai voi olla edellisen vuoden joulukuussa.
Esimerkkejä:
| ISO-viikko | Vuosi | Maanantai | Sunnuntai |
|---|---|---|---|
| W1 | 2025 | 30. joulukuuta 2024 | 5. tammikuuta 2025 |
| W1 | 2026 | 29. joulukuuta 2025 | 4. tammikuuta 2026 |
| W1 | 2027 | 4. tammikuuta 2027 | 10. tammikuuta 2027 |
| W1 | 2028 | 3. tammikuuta 2028 | 9. tammikuuta 2028 |
Vuoden 2025 viikko 1 alkaa joulukuussa 2024. Vuoden 2026 viikko 1 alkaa joulukuussa 2025.
Tämä tarkoittaa:
- 29.–31.12.2025 ovat ISO-viikolla 1 vuoden 2026 puolella, eivät vuoden 2025.
- Jos joku sanoo ”toimitus viikolla 1 vuonna 2026”, takaraja on viikko, joka alkaa 29.12.2025.
Myös käänteinen ansa on olemassa: joidenkin vuosien viimeiset päivät kuuluvat seuraavan vuoden viikkoon 1, eivät kuluvan vuoden viimeiseen viikkoon. Käytä aina ISO-viikkovuotta (Pythonissa %G, PostgreSQL:ssä isoyear), kun merkitset viikkoja — älä kalenterivuotta.
Koko päivämääräväli mille tahansa viikolle
Kun sinulla on maanantai, loppu on helppoa:
| Päivä | Siirto maanantaista |
|---|---|
| Maanantai | +0 |
| Tiistai | +1 |
| Keskiviikko | +2 |
| Torstai | +3 |
| Perjantai | +4 |
| Lauantai | +5 |
| Sunnuntai | +6 |
Viikon W aikaväli on: [maanantai, maanantai + 6 päivää].
Työpäiviä (ma–pe) varten: [maanantai, maanantai + 4 päivää].
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
Pythonissa on myös sisäänrakennettu käänteiseen suuntaan (päivämäärä → ISO-viikko):
d = date(2026, 6, 4)
iso_year, iso_week, iso_weekday = d.isocalendar()
print(iso_year, iso_week) # 2026 23
Käytä d.isocalendar().year (ei d.year), kun tarvitset ISO-vuoden — ne eroavat vuodenvaihteessa.
Käänteiseen hakuun fromisocalendar-metodilla (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) on siistein tapa, jos käytössäsi on Python 3.8 tai uudempi.
JavaScript
JavaScriptissa ei ole natiivia ISO-viikkotukea. Tässä käsin tehty toteutus:
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
date-fns-kirjastolla:
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 hoitaa kaikki reunatapaukset oikein ja on suositeltava vaihtoehto tuotantokoodiin.
Excel ja Google Sheets
Excelissä ei ole suoraa ”viikkonumero → päivämäärä” -funktiota, mutta sen voi rakentaa kaavalla.
ISO-viikon W maanantai vuonna Y:
=DATE(Y,1,4) - WEEKDAY(DATE(Y,1,4),2) + 1 + (W-1)*7
Tämä tarkoittaa:
DATE(Y,1,4)— 4. tammikuutaWEEKDAY(...,2)— viikonpäivä, jossa maanantai=1 ja sunnuntai=7- vähentämällä saat viikon 1 maanantain
- lisäämällä
(W-1)*7siirryt kohdeviikolle
Koko aikavälille sunnuntai on:
=Monday_formula + 6
Esimerkki (A1 = vuosi, B1 = viikko):
Monday: =DATE(A1,1,4) - WEEKDAY(DATE(A1,1,4),2) + 1 + (B1-1)*7
Sunday: =Monday_cell + 6
Muotoile solut päivämääriksi. Vuodelle 2026, viikolle 1, saat maanantaiksi 29.12.2025 — mikä on oikein.
Käänteinen (päivämäärä → ISO-viikko): käytä ISOWEEKNUM(date). ISO-vuodelle tarvitaan ISOWEEKNUM-artikkelin kiertotapa, koska Excelissä ei ole natiivifunktiota ISO-vuodelle.
SQL
PostgreSQL tukee ISOa kattavimmin:
-- 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;
Selkeä tapa PostgreSQL:ssä käyttää to_date-funktiota ISO-muotoilukoodeilla:
-- 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)
Tämä on yksinkertaisin PostgreSQL-tapa: muodosta merkkijono YYYYWWD ja jäsennä se ISO-koodeilla.
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
US-tyylinen viikkonumero → päivämäärät
Jos viikkonumero tulee US-tyylisestä järjestelmästä (viikko 1 = sisältää 1.1., viikot alkavat sunnuntaina tai maanantaina), kaava on yksinkertaisempi, koska vuodenvaihdeongelmaa ei ole:
Viikon alku (sunnuntai-pohjainen):
Week_start = DATE(Y, 1, 1) + (W - 1) × 7 - WEEKDAY(DATE(Y, 1, 1), 1)
missä WEEKDAY palauttaa 1 sunnuntaille … 7 lauantaille.
Mutta US-tyyliset viikkonumerot ovat aikatauluissa ja logistiikassa paljon harvinaisempia kuin ISO. Jos joku antaa viikkonumeron määrittelemättä järjestelmää, oleta ISO — erityisesti kansainvälisissä tai eurooppalaisissa yhteyksissä.
Vuosi 2026: pikaopas ISO-viikoille 1–10 ja 48–53
| ISO-viikko | Vuosi | Maanantai | Sunnuntai |
|---|---|---|---|
| W1 | 2026 | 29.12.2025 | 4.1.2026 |
| W2 | 2026 | 5.1.2026 | 11.1.2026 |
| W3 | 2026 | 12.1.2026 | 18.1.2026 |
| W4 | 2026 | 19.1.2026 | 25.1.2026 |
| W5 | 2026 | 26.1.2026 | 1.2.2026 |
| W6 | 2026 | 2.2.2026 | 8.2.2026 |
| W7 | 2026 | 9.2.2026 | 15.2.2026 |
| W8 | 2026 | 16.2.2026 | 22.2.2026 |
| W9 | 2026 | 23.2.2026 | 1.3.2026 |
| W10 | 2026 | 2.3.2026 | 8.3.2026 |
| ... | |||
| W48 | 2026 | 23.11.2026 | 29.11.2026 |
| W49 | 2026 | 30.11.2026 | 6.12.2026 |
| W50 | 2026 | 7.12.2026 | 13.12.2026 |
| W51 | 2026 | 14.12.2026 | 20.12.2026 |
| W52 | 2026 | 21.12.2026 | 27.12.2026 |
| W53 | 2026 | 28.12.2026 | 3.1.2027 |
Huomaa: vuoden 2026 viikko 1 alkaa 29.12.2025. Huomaa myös: vuoden 2026 viikko 53 päättyy 3.1.2027 — 2026 on 53-viikkoinen vuosi.
Yleisimmät virheet tiivistettynä
Vuoden puuttuminen. ”Viikko 8” on epäselvä. Käytä aina muotoa 2026-W08 tai vastaavaa.
Kalenterivuoden käyttäminen ISO-viikkovuoden sijaan. 29.12.2025 on ISO-viikolla 1 vuonna 2026, ei 2025. Jos tallennat sen vuodelle 2025, se päätyy väärään “lokeroon”.
Olettaa, että viikko 1 alkaa 1.1. Monina vuosina se alkaa 29., 30. tai 31.12. Jos haluat, että 1.1. on aina viikossa 1, käytät US-järjestelmää, et ISOa.
Off-by-one maanantaikaavassa. 4. tammikuuta -ankkuri on olennainen — ei 1. tammikuuta (joka voi kuulua edellisen vuoden viimeiseen viikkoon). Jos käytät 1. tammikuuta ankkurina, saat vääriä tuloksia vuosina, joissa 1. tammikuuta osuu viikon loppupuolelle.
Vuodenvaihteen testaamatta jättäminen. Kaikki päivämäärälogiikka tulisi testata päivillä 28.–31.12. ja 1.–4.1. Näinä 4–7 päivänä sijaitsevat kaikki reunatapaukset.
Käytä ISO Week Number Calculator -työkalua hakeaksesi minkä tahansa viikkonumeron päivämäärävälin, tai tarkista current week number ja tämän päivän ISO-viikkopäivämääräväli.