At lægge måneder til en dato er sværere end det lyder
At lægge 7 dage til en dato er simpelt. Du tager et tal, lægger 7 til, og så er det gjort. At lægge en måned til er et helt andet problem.
Problemet er, at måneder har forskellig længde. Januar har 31 dage. Februar har 28, nogle gange 29. Hvis du er på 31. januar og lægger én måned til, lander du på 31. februar — som ikke findes.
Alle kalenderbiblioteker, regneark og databaser har en mening om, hvad der skal ske derefter.
Hvad de fleste værktøjer gør
Den mest almindelige måde at håndtere det på er at springe til den sidste dag i målmåneden. 31. januar + 1 måned = 28. februar (eller 29 i skudår). 31. marts + 1 måned = 30. april.
Dette kaldes end-of-month clamping og det er hvad Excel, Google Sheets, Pythons dateutil og de fleste datobiblioteker gør som standard.
Det er fornuftigt, men det skaber et subtilt problem: operationen er ikke reversibel. Hvis du lægger én måned til 31. januar, får du 28. februar. Hvis du så trækker én måned fra, får du 28. januar — ikke 31. januar. Du har mistet tre dage.
Overflow-metoden
Nogle systemer lader datoen overflyde ind i næste måned i stedet for at begrænse den. 31. januar + 1 måned = 3. marts (eller 2. marts i skudår, fordi februar har 29 dage).
Det bevarer det samlede antal dage, men resultatet lander i en helt anden måned end du ville forvente. Det er overraskende og normalt forkert fra brugerens perspektiv.
SQL's INTERVAL-syntaks i nogle databaser gør dette afhængigt af konfiguration. Det er let at blive brændt hvis du ikke er opmærksom på, hvilken adfærd du arbejder med.
At lægge år til har det samme problem
29. februar findes kun i skudår. Læg ét år til 29. februar 2024, og du får 29. februar 2025 — som ikke findes. Clamping giver dig 28. februar 2025.
Samme adfærd, samme afvejninger.
Hvornår dette faktisk forårsager fejl
Abonnementsafgifter er det klassiske eksempel. En bruger tilmelder sig 31. januar. Deres næste faktureringsdato er 28. februar. Derefter 28. marts. Derefter 28. april. Hver måned efter den første bliver de faktureret 2-3 dage tidligere end de ville forvente.
Tilbagevendende kalenderhændelser har det samme problem. "Hver måned på den 31." bliver lydløst til "hver måned på den sidste dag" for måneder, der ikke når til 31.
Låneafbetalingsplaner, lønudbetalingsdatoer og alt med "månedlig" gentagelse rammer denne grænsetilfælde til sidst.
At lægge dage til har ikke dette problem
Hvis du skal udtrykke "30 dage fra nu" i stedet for "én måned fra nu", skal du bare lægge 30 dage til. Resultatet er entydig og reversibel.
Sondringen betyder noget: en 30-dages faktureringscyklus og en månedlig faktureringscyklus er ikke det samme, og de divergerer hurtigt over tid.
Hvad man skal tjekke i dit værktøj eller bibliotek
Før du stoler på datoaddition i et system, er det værd at vide:
- Begrænser det eller lader det overflyde på månedslutsedatoer?
- Bevarer det dagen i måneden over flere additioner, eller begrænserer det igen hver gang?
- For skudår-grænsetilfælde, hvad sker der på 29. feb + 1 år?
Date Calculator viser dig det nøjagtige resultat for enhver dato og offset — nyttig til at tjekke sanity før du forpligter dig til en beregning i kode.


