Att lägga till månader på ett datum är svårare än det låter
Att lägga till 7 dagar på ett datum är enkelt. Du tar ett tal, adderar 7, klart. Att lägga till en månad är något helt annat.
Problemet är att månader har olika längd. Januari har 31 dagar. Februari har 28, ibland 29. Om du är på 31 januari och adderar en månad, hamnar du på 31 februari — vilket inte finns.
Varje kalenderbibliotek, kalkylprogram och databas har en åsikt om vad man ska göra då.
Vad de flesta program gör
Det vanligaste är att hoppa till den sista dagen i målmånaden. 31 januari + 1 månad = 28 februari (eller 29 under ett skottår). 31 mars + 1 månad = 30 april.
Detta kallas begränsning till månadsslutet och det är vad Excel, Google Sheets, Pythons dateutil och de flesta datumbibliotek gör som standard.
Det är rimligt, men det skapar ett subtilt problem: operationen går inte att vända. Om du adderar en månad till 31 januari får du 28 februari. Om du sedan subtraherar en månad får du 28 januari — inte 31 januari. Du har förlorat tre dagar.
Överflödesmetoden
Vissa system låter datumet flöda över i nästa månad istället för att begränsa det. 31 januari + 1 månad = 3 mars (eller 2 mars under ett skottår, eftersom februari har 29 dagar).
Detta bevarar det totala antalet dagar, men resultatet hamnar i en helt annan månad än du avsåg. Det är överraskande och vanligtvis fel ur användarens perspektiv.
SQLs INTERVAL-syntax gör detta i vissa databaser beroende på konfiguration. Det är lätt att få problem om du inte är medveten om vilket beteende du arbetar med.
Att lägga till år har samma problem
29 februari finns bara under skottår. Lägg till ett år på 29 februari 2024 och du får 29 februari 2025 — vilket inte finns. Begränsning ger dig 28 februari 2025.
Samma beteende, samma avvägningar.
När detta faktiskt orsakar buggar
Prenumerationsfakturering är det klassiska exemplet. En användare registrerar sig 31 januari. Nästa faktureringsdatum är 28 februari. Sedan 28 mars. Sedan 28 april. Varje månad efter den första faktureras de 2–3 dagar tidigare än de förväntar sig.
Återkommande kalenderhändelser har samma problem. "Varje månad på den 31:a" blir helt tyst "varje månad på den sista dagen" för månader som inte når till 31.
Låneamortiseringsscheman, lönedagar och allt med återkommande månadscykler stöter på detta kantfall förr eller senare.
Att lägga till dagar har inte det här problemet
Om du behöver uttrycka "30 dagar från nu" istället för "en månad från nu", lägg bara till 30 dagar. Resultatet är entydigt och reversibelt.
Skillnaden är viktig: en 30-dagarsfaktureringscykel och en månadsfaktureringscykel är inte samma sak, och de skiljer sig åt snabbt över tid.
Vad du bör kontrollera i ditt verktyg eller bibliotek
Innan du förlitar dig på datumaddition i något system är det värt att veta:
- Begränsar eller överflödar det på månadsslutsatum?
- Bevarar det dagen i månaden genom flera additioner, eller begränsar det på nytt varje gång?
- För skottårskantfall, vad händer på 29 feb + 1 år?
Datumräknaren visar dig det exakta resultatet för ett valfritt datum och förskjutning — användbar för att kontrollera sanningen innan du implementerar en beräkning i kod.


