Een maand bij een datum optellen is lastiger dan het lijkt

7 dagen bij een datum optellen is simpel. Je neemt een getal, telt er 7 bij op, klaar. Een maand optellen is een heel ander verhaal.

Het probleem is dat maanden verschillende lengtes hebben. Januari heeft 31 dagen. Februari heeft 28, soms 29. Als je op 31 januari bent en je telt één maand op, kom je uit op 31 februari — wat niet bestaat.

Elke kalenderbibliotheek, spreadsheet en database heeft een eigen mening over wat nu te doen.

Wat de meeste tools doen

Het meest gangbare gedrag is om naar de laatste dag van de doelmaand te springen. 31 januari + 1 maand = 28 februari (of 29 in een schrikkeljaar). 31 maart + 1 maand = 30 april.

Dit heet end-of-month clamping en is wat Excel, Google Sheets, Python's dateutil en de meeste datumbiblotheken standaard doen.

Het is logisch, maar het creëert een subtiel probleem: de operatie is niet omkeerbaar. Als je één maand bij 31 januari optelt, krijg je 28 februari. Trek je vervolgens één maand af, dan krijg je 28 januari — niet 31 januari. Je bent drie dagen verloren.

De overflowbenadering

Sommige systemen laten de datum in plaats van af te kappen overstromen naar de volgende maand. 31 januari + 1 maand = 3 maart (of 2 maart in een schrikkeljaar, omdat februari 29 dagen heeft).

Dit behoudt het totale aantal dagen, maar het resultaat landt in een geheel ander maand dan je bedoelde. Het is verrassend en meestal niet wat je van gebruikersperspectief wilt.

SQL's INTERVAL-syntaxis in sommige databases doet dit afhankelijk van de configuratie. Je loopt er gemakkelijk tegenaan als je niet weet welk gedrag je gebruikt.

Jaren optellen heeft hetzelfde probleem

29 februari bestaat alleen in schrikkeljaren. Tel één jaar op bij 29 februari 2024, dan krijg je 29 februari 2025 — wat niet bestaat. Met clamping krijg je 28 februari 2025.

Hetzelfde gedrag, dezelfde afwegingen.

Wanneer dit daadwerkelijk bugs veroorzaakt

Abonnementsfacturering is het klassieker voorbeeld. Een gebruiker meld zich aan op 31 januari. Hun volgende factuurdatum is 28 februari. Daarna 28 maart. Daarna 28 april. Elke maand na de eerste worden ze 2-3 dagen eerder gefactureerd dan ze zouden verwachten.

Terugkerende agendagebeurtenissen hebben hetzelfde probleem. "Elke maand op de 31e" wordt stilzwijgend "elke maand op de laatste dag" voor maanden die niet tot 31 gaan.

Terugbetalingsschema's voor leningen, salarisdatums, en alles met "maandelijks" terugkeer loopt uiteindelijk tegen dit randgeval aan.

Dagen optellen heeft dit probleem niet

Als je "30 dagen vanaf nu" wilt uitdrukken in plaats van "één maand vanaf nu", tel je simpelweg 30 dagen op. Het resultaat is ondubbelzinnig en omkeerbaar.

Het verschil is belangrijk: een 30-daagse factuurcyclus en een maandelijkse factuurcyclus zijn niet hetzelfde, en ze wijken snel uiteen over tijd.

Wat je moet controleren in je tool of bibliotheek

Voordat je op datumoptelling in enig systeem vertrouwt, is het nuttig om te weten:

  • Klapt het af of overstroomt het bij maandeinde-datums?
  • Behoudt het de dag van de maand over meerdere optellingen, of wordt het elke keer opnieuw afgekapt?
  • Wat gebeurt er bij schrikkeljaar-randgevallen, bijvoorbeeld 29 februari + 1 jaar?

De Date Calculator toont je het exacte resultaat voor elke datum en verschuiving — handig om ter controle na te gaan voordat je je aan een berekening in code vastlegt.

Gerelateerde artikelen