Dodavanje mjeseci datumu je teže nego što zvuči

Dodavanje 7 dana datumu je jednostavno. Uzmete broj, dodate 7, gotovo. Dodavanje mjeseca je potpuno drugačiji problem.

Problem je što mjeseci imaju različite duljine. Siječanj ima 31 dan. Veljača ima 28, ponekad 29. Ako ste na 31. siječnja i dodate jedan mjesec, dolazite na 31. veljače — što ne postoji.

Svaka biblioteka za rad s kalendarima, tablica i baza podataka ima svoju ideju što dalje.

Što rade većina alata

Najčešće ponašanje je prilagođavanje zadnjemu danu mjeseca odredišta. 31. siječnja + 1 mjesec = 28. veljače (ili 29. u prestupnoj godini). 31. ožujka + 1 mjesec = 30. travnja.

To se zove prilagođavanje kraju mjeseca i to je što Excel, Google Sheets, Python dateutil i većina biblioteka za rad s datumima rade po zadanoj vrijednosti.

Ima smisla, ali stvara suptilan problem: operacija nije reverzibilna. Ako dodate jedan mjesec na 31. siječnja, dobivate 28. veljače. Ako zatim oduzmete jedan mjesec, dobivate 28. siječnja — ne 31. siječnja. Izgubili ste tri dana.

Pristup prelijevanja

Neki sustavi dozvoljavaju datumu da se preljeva u sljedeći mjesec umjesto prilagođavanja. 31. siječnja + 1 mjesec = 3. ožujka (ili 2. ožujka u prestupnoj godini, jer veljača ima 29 dana).

To čuva ukupan broj dana, ali rezultat pada u potpuno drugi mjesec nego što ste namjeravali. Iznenađujuće je i obično pogrešno sa korisnikovog stajališta.

SQL INTERVAL sintaksa u nekim bazama podataka radi to ovisno o konfiguraciji. Lako se može dogoditi problem ako niste svjesni koji ste dio ponašanja aktivirali.

Dodavanje godina ima isti problem

29. veljače postoji samo u prestupnim godinama. Dodate jednu godinu na 29. veljače 2024., dobivate 29. veljače 2025. — što ne postoji. Prilagođavanje vam daje 28. veljače 2025.

Isto ponašanje, isti kompromisi.

Kada to zapravo uzrokuje greške

Naplata pretplate je klasičan primjer. Korisnik se registrira 31. siječnja. Njihov sljedeći datum naplate je 28. veljače. Zatim 28. ožujka. Zatim 28. travnja. Svaki mjesec nakon prvoga, naplaćeni su 2-3 dana ranije nego što bi očekivali.

Ponavljajući događaji u kalendaru imaju isti problem. "Svakog mjeseca 31." tiho postaje "svakog mjeseca zadnji dan" za mjesece koji ne dosežu 31.

Raspored otplate kredita, datumi isplata plaća i sve s "mjesečnom" ponovljivošću prije ili kasnije nađu na ovoj granici.

Dodavanje dana nema ovaj problem

Ako trebate izraziti "30 dana od sada" umjesto "jedan mjesec od sada", samo dodajte 30 dana. Rezultat je nedvosmislen i reverzibilan.

Razlika je važna: 30-dnevni ciklus naplate i mjesečni ciklus naplate nisu ista stvar i brzo se razilaze tijekom vremena.

Što provjeriti u vašem alatu ili biblioteci

Prije nego što se oslonite na zbrajanje datuma u bilo kojem sustavu, vrijedi znati:

  • Prilagođava li se ili preliva na datume kraju mjeseca?
  • Čuva li dan mjeseca kroz više zbrajanja ili se ponovno prilagođava svaki put?
  • Za graničke slučajeve prestupne godine, što se dogodi na 29. veljače + 1 godinu?

Kalkulator datuma vam pokazuje točan rezultat za bilo koji datum i razliku — korisno za provjeru zdravstvenosti prije nego što se obavežete na izračun u kodu.

Povezani članci