Mind Fuck

 I don't know whether I've finally started losing my brain crunching abilities or this problem is making my mind melt in very specific ways. This should be absolutely trivial trivial. Not even worth thinking about. And yet.

Here is a very simple conceptual task.

Report when an expiry date is hit. Report when an expiry date is 1 month or less away from being hit. Report when an expiry date is 2 months or less away from being hit.

Easy.

We might break it down like this ( bearing in mind that dates in the past are smaller than dates in the future ).

Check the date against today, if its less than today, its expired.

Check the date less a month against today ( ie, 1 month sooner ). If its less than today its expiring soon.

Check the date less 2 months against today. If its less than today, its expiring later.

A bit less wordy and a bit more psuedo codey it would look like this :

If ExpiryDate<Today Then EXPIRED

Else If ExpiryDate-1 Month<Today Then Expiring Soon

Else If ExpiryDate-2 Month<Today Then Expiring Later

Lovely. Easy.

However. If you are checking a lot of dates, it's not very efficient. Let's say you have, ooh, I don't know, 1,000 dates. Then for every date of that thousand you need to work out, the date less 1 month, the date less 2 months. So. You have 2,000 date calculations. And then 3,000 date checks. Which by todays standards is tickety boo. No one cares. Milliseconds of work. But the point stands. It's inherently not scalable. You're doing a lot of work when you don't have to.

It would be better if we didn't fuck with the dates, and just fucked with Today - just the once. Algebra basics.

So. Go. Solve it. Write the thing that doesnt do a bazillion calcs, just alters today, and leaves the rest of the dates alone, using the fact that a -1 = b is the same as a = b + 1.

...

Write down what that looks like.

...

For the life of me this made me stall for a good 30 minutes, increasingly sure that I had finally succumbed to old age and could no longer Think Goodly.

Eventually I got there. But goddamn. On reflection, I think it was the slightly unintuitive algebra flip that screwed with my head. So. Lets actually do it.

 Lets take our date comparison and write down in algebra what they look like. Instead of using less than, we'll just do equals. This will make our algebra obvious. So we get :

X = Y ( this is equivalent to ExpiryDate<Today )

X-1 = Y ( this is equivalent to ExpiryDate - 1 Month < Today )

X-2 = Y ( this is equivalent to ExpiryDate - 2 Month < Today )

Where X is the variable expiry date, and crucially Y is today which is static ( for the query run time ).

So algebra tells us this :

X-1 = Y is equivalent to X = Y+1

Super basic stuff. And for the real basic you can check it out by plugging a value into it.

4 - 1 = 3, and, 4 = 3 + 1. Legit.

Slightly mind bendy, the date logic then becomes :

If ExpiryDate < Today Then EXPIRED

Else If ExpiryDate < Today+1 Then Expiring Soon

Else If ExpiryDate < Today+2 Then Expiring Sooner

Intuitively this reads as bonkers to me. The date you are checking against is getting bigger - into the future. And your expiry is staying the same. Madness. Except it isn't. What you're effectively doing here is looking into the future. In 1 months time ( Today + 1 ), is our expiry date now a problem ? How about in 2 months time ( Today + 2 ).

I find it slippery. My mind easily consumes the whole, take an expiry date, then take a month from it, then take 2 months off it, and compare against TODAY. The other way around - add time to today and check against a static expiry date... blows my mind a little.

The actual thing I got hung up which didn't help, is I had inadvertently reversed my add of a month and was actually doing Today - 1, when trying to peer into the future. Absolutely fucked. And didn't help with my wrestling with dates.

I dunno.

I could be an idiot. Getting old. And losing it. Or it could just a little unintuitive. Or perhaps because its 1AM and I got the minus wrong.

What do you think ?

The final crude form - in MariaDB sql - ended up looking like this :

SELECT *, IF(notdbsexpiry<@Today, 1, 0) as Expired, IF(notdbsexpiry>@Today AND notdbsexpiry<=@Warning, 1, 0) as Warning, IF(notdbsexpiry>@Warning AND notdbsexpiry<=@Alert, 1, 0) as Alert  FROM rep_DBSExpiry

where @Today = today, @Warning = today + 1 month and @Alert = today + 2 months.

It still bends my mind a bit.

Comments

Popular posts from this blog

Feb 29

May 9

Nov 6