Kuukausien lisääminen päivämäärään on vaikeampaa kuin miltä se kuulostaa
Päivämäärään 7 päivän lisääminen on helppoa. Otat luvun, lisäät 7, ja olet valmis. Kuukauden lisääminen on täysin eri ongelma.
Ongelma on siinä, että kuukausilla on eri pituudet. Tammikuussa on 31 päivää. Helmikuussa on 28, joskus 29. Jos olet 31. tammikuuta ja lisäät yhden kuukauden, päädy 31. helmikuuhun — jota ei ole olemassa.
Jokaisella kalenterikirjastolla, taulukkolaskentaohjelmalla ja tietokannalla on oma mielipide siitä, mitä seuraavaksi tehdään.
Mitä useimmat työkalut tekevät
Yleisin käyttäytyminen on siirtää päivämäärä kohdekuukauden viimeiseen päivään. 31. tammikuuta + 1 kuukausi = 28. helmikuuta (tai 29 karkausvuonna). 31. maaliskuuta + 1 kuukausi = 30. huhtikuuta.
Tätä kutsutaan kuukauden lopun rajaamiseksi, ja näin toimivat Excel, Google Sheets, Pythonin dateutil ja useimmat pääiväkirjastot oletuksena.
Se on järkevää, mutta aiheuttaa hienovaraisen ongelman: operaatio ei ole käännettävissä. Jos lisäät yhden kuukauden 31. tammikuuhun, saat 28. helmikuuta. Jos sitten vähennät yhden kuukauden, saat 28. tammikuuta — et 31. tammikuuta. Olet menettänyt kolme päivää.
Ylivuoto-lähestymistapa
Jotkut järjestelmät antavat päivämäärän ylivuotaa seuraavaan kuukauteen rajoittamisen sijaan. 31. tammikuuta + 1 kuukausi = 3. maaliskuuta (tai 2. maaliskuuta karkausvuonna, koska helmikuulla on 29 päivää).
Tämä säilyttää päivien kokonaismäärän, mutta tulos päätyy täysin eri kuukauteen kuin aiot. Se on yllättävää ja yleensä väärää käyttäjän näkökulmasta.
SQL:n INTERVAL-syntaksi joissakin tietokannoissa toimii näin riippuen asetuksista. On helppo joutua pulaan, jos et ole tietoinen siitä, kumpi käyttäytyminen on käytössä.
Vuosien lisäämisellä on sama ongelma
29. helmikuuta on olemassa vain karkausvuosina. Lisää yksi vuosi 29. helmikuuhun 2024 ja saat 29. helmikuuta 2025 — jota ei ole olemassa. Rajaaminen antaa sinulle 28. helmikuuta 2025.
Sama käyttäytyminen, samat kompromissit.
Milloin tämä aiheuttaa todellisia virheitä
Tilauslaskutus on klassinen esimerkki. Käyttäjä rekisteröityy 31. tammikuuta. Hänen seuraava laskutuspäivänsä on 28. helmikuuta. Sitten 28. maaliskuuta. Sitten 28. huhtikuuta. Jokaisen kuukauden jälkeen ensimmäistä, hänelle laskutetaan 2–3 päivää aikaisemmin kuin hän odottaisi.
Toistuvilla kalenteritapahtumilla on sama ongelma. "Joka kuukausi 31. päivänä" hiljaisen hiljaa muuttuu "joka kuukauden viimeisenä päivänä" kuukauksille, joilla ei ole 31. päivää.
Lainan takaisinmaksuaikataulut, palkkapäivät ja kaikki kuukausittaisella toistolla tehdyt asiat törmäävät lopulta tähän rajatapaukseen.
Päivien lisäämisellä ei ole tätä ongelmaa
Jos haluat ilmaista "30 päivää tästä päivästä" sen sijaan että "yksi kuukausi tästä päivästä", lisää vain 30 päivää. Tulos on yksiselitteinen ja käännettävissä.
Ero on tärkeä: 30 päivän laskutussykli ja kuukausilaskutussykli eivät ole sama asia, ja ne eroavat toisistaan nopeasti ajan mittaan.
Mitä tarkistaa omasta työkalustasi tai kirjastostasi
Ennen kuin luotat päivämäärän lisäämiseen missään järjestelmässä, kannattaa tietää:
- Rajaaako vai ylivuotaako se kuukauden lopun päivämäärissä?
- Säilyttääkö se päivän numeroa useiden lisäysten yli vai rajaako se uudelleen joka kerta?
- Karkausvuoden rajatapauksissa, mitä tapahtuu 29. helmikuussa + 1 vuosi?
Date Calculator näyttää sinulle tarkan tuloksen mille tahansa päivämäärälle ja siirtymälle — hyödyllinen ennen kuin vahvistat laskennan koodissa.


