As someone who had some fun (er, not) during the Y2K debacle, I can promise you it's a lot more than just altering databases or patching a few bits of code. Sometimes the code is impossible to understand. For example, one program named all the variables after types of alcohol and had lines like:
compute martini equals gin plus vermouth.
(Yeah, I used to hack COBOL, too).
Other times there would be absolutely critical systems which were developed, but were tucked away on an unknown server and we'd find out about them at the last minute and panic trying to figure out if they would work correctly.
And if you get into languages who have severe bondage and discipline on datatypes, finding out that the subtly altered data that works in one system is blowing up another one just isn't fun.
What's worse: sometimes the logic just assumes that dates can't be past a certain time. Ooh, let's set the date to maxint of this data type and use that as the cutoff in our code. This code won't exist then, right? Naturally, the tests hard-code a datetime in them and it won't show up even when clocks are deliberately set forward to test the code. Of course, I've hacked on code that was written before I was born, so the whole "this code won't exist then" actually means "I won't be working here then".
Yeah I figure it might be more complex for other code but I seriously only use 32bits in the database for time while we are still using mechanical storage.
The actual code for time will work fine with 64bit integers, well once it's compiled correctly in a 64bit environment which is a huge percentage of servers right now.
I'm just too old school to waste 4 bytes on millions of rows (and for index storage which does bloat) when I am not dealing with future dates.
Right now ALTER in most SQL databases is kinda slow and not done in parallel but that is certainly going to change and next-gen SSD in this decade will also change everything.
It's not the ALTER that's expensive, it's the people who have to figure out that the ALTER has to be run, set up testing environments, run test cases, verify them, run the actual update in production, etc. (Or: possibly miss it and thus end up with bad data or crashes in production.)
I'd think the number of cases in which it's a worthwhile tradeoff for new development to save 4 bytes times even tens of millions of rows (each million costs you 4 MB, the size of a song) is vanishingly small today.
If you only have 5000 products, you might as well use a 16 bit field. If you only have 10 million messages, you might as well use a 32 bit field. If you only deal with times before 2038, you might as well use a 32 bit field. It's a bug if the code isn't flexible, but there is no reason to waste extra space in the database to store 0s.
Just like there was never any point in keeping the first two digits of a year? Until Y2K approached and tons of code was still in production that hadn't ever been expected to live that long. It cost companies a lot of money. Why make the same mistake again?
I'm not saying optimizations like that are never worth it, but as a general rule the case would have to be made extremely well for me to ever sign off on it. And I bet in the huge majority of cases, the time cost of making that case would exceed the extra storage cost for using "unoptimized" data structures.
I can't find it at the moment but I remember reading a study showing that even with the cost of fixing Y2K issues it was still an economically sound decision to use two digit years given the historical cost of storage. In other words it was cheaper to fix the problem in 1999 than it would have been to buy enough mainframe storage in 1979 to store the extra two digits.
Hah! Yeah, I could definitely see that being true. It was hasty of me to refer to that as "a mistake": as you say, that was a world in which every byte was several orders of magnitude more expensive.
To save a similar amount of money on storage today of course it'd probably have to be tens or hundreds of kilobytes wasted per record. That kind of an optimization would very often still be worth looking into and optimizing for.
We're talking about a database here, not the code that processes a few records at a time. That code should be future proofed. But while the database design should be future proof, the exact settings don't have to be. Keep things properly isolated and nobody will ever know how many bits the database takes to store a value, and you can change it behind their backs with a single ALTER.
And someone hasn't written code based and tested on the 32bit date that then starts blowing (or even worse subtly making mistakes) up when you switch to 64bits...
That code is going to work/break the same with or without the database being expanded. Only truly ridiculous code would depend on the fact that inserting a date in 2040 causes the database to reject that transaction. Anything else in the code involving dates should have unit tests but is entirely independent of the database.
Other times there would be absolutely critical systems which were developed, but were tucked away on an unknown server and we'd find out about them at the last minute and panic trying to figure out if they would work correctly.
And if you get into languages who have severe bondage and discipline on datatypes, finding out that the subtly altered data that works in one system is blowing up another one just isn't fun.
What's worse: sometimes the logic just assumes that dates can't be past a certain time. Ooh, let's set the date to maxint of this data type and use that as the cutoff in our code. This code won't exist then, right? Naturally, the tests hard-code a datetime in them and it won't show up even when clocks are deliberately set forward to test the code. Of course, I've hacked on code that was written before I was born, so the whole "this code won't exist then" actually means "I won't be working here then".