math

Difference between two dates using Math


I have read a formula to determine the difference between two date using math with O(1) time complexity

365*year + year/4 - year/100 + year/400 + (153*month - 457)/5 + day - 306

with considering

if month number less than 3 , year-=1 and month+=12

the following link show the whole code which i quote from

https://codeforces.com/contest/304/submission/3715756

So if someone can explain it please ?


Solution

  • This is not a full answer but it is some explanation.

    First of all the

    if month number less than 3 , year-=1 and month+=12

    is used to effectively start the year from March moving the highly irregular February to the end. Actually this is how this calendar was originally designed which you still can see in the names of some month like October or December (you probably hear that Oct = 8 and Dec = 10).

    The 365*year + year/4 - year/100 beat is just handling the leap years.

    The day part is also clear.

    Now let's remove the bits that are irrelevant when we subtract two values and get this value for month

    30*month + (3*month - 2)/5
    

    I don't know the logic how it was got (I only have a guess at the end) but I can say why it works. The 30*month bit is obvious. And now when we moved the February to its last position, all the month in the middle of the year have either 30 or 31 day. Let's write them down:

    We don't care about February as there are no months after it (we cared about that before). We only care about this +1 day since the next month after that!

    So what we need now is some formula that would match that distribution of +1 and +0. And it appears that the value

    (3*month - 2)/5
    

    with integer division does exactly that. You can easily verify it by hand.

    Probably the way to come up with this idea was to notice that the year (except for February) follows the following 5-month-cycle

    +1 +0 +1 +0 +1

    I mean March-July and August-December both match it exactly and then January is again +1 so it is like the first element of the next cycle.