The code worked differently when the moon was full (2021)
hanselman.com
hanselman.com
One of our customer required perfect uptime, which was a problem with the GetTickCount wraparound described here
Our solution was to run under NuMega SoftICE [1] and once a month, or so, dispatch an engineer to the customer to simultaneously patch the kernel value for the tick count and also the expected value in our software (and also clean up various handle based cruft)
This worked for years. Unfortunately the engineer in question was also an alcoholic, so a particularly spectacular bender spoiled an approx 3 year uptime
In all honesty, these are the kind of clients I politely point at someone else. They seldom have the resources to fund the requirement, and one absurd requirement leads to another.
I'm sure they had good reason, and good on you for pulling it off, but trying to keep Windows 3.1 up for multiple years sounds like a risky task to take on. Who knew there wasn't another time-sensitive bug in there that kicked in at say 365 days?
To be fair the insane requirements I've come across are just delusional so they're easy to walk away from.
Do anyone else know of other places to find stories like this?
Most computers are 64 bits for decades now. It takes same resources to add/subtract/compare int64 compared to int32. No reason to use 32-bit integers for time, when I write C++ I use GetTickCount64() API introduced in Vista.
The C# equivalent is Environment.TickCount64, but there’s no need because unlike many other languages, C# standard library comes with a good support for dates, times, and time intervals. Instead of integers for elapsedInterval and requiredInterval variables, I prefer TimeSpan type. Safer, more readable, and potentially higher resolution because TimeSpan keeps int64 number of 100 nanoseconds ticks.
Desktops and laptops and servers, sure. There's an awful lot of 32bit processors in industrial controllers.
All modern compilers support such types, so the choice does not require any work for the programmer. Even on 32-bit MCUs, the extra overhead for using 64-bit time quantities is almost always negligible, because normally only additions and subtractions are done with these values. Multiplications and divisions, which are slow on 32-bit MCUs, are used very seldom for time values.
The failure to use such types is a serious programmer mistake, which does not have any excuse, already for at least three decades or more.
In microcontrollers it is even easier to always use the right types for time values, because normally there are no backward compatibility concerns.
Many microcontrollers have only small hardware tick counters, e.g. 16-bit counters, but it is easy to extend them in software to 64-bit by having an interrupt on overflow that increments the high words of the 64-bit software tick counter (when reading such split software-hardware tick counters, modifications in progress must be detected and the read must be retried, like for any other lockless data that are shared between concurrent threads).
Unless they were using that system to play NetHack:
I've seen games that crash if your timestamps were negative. So if your computer has been on for a while, and a game isn't running properly, reboot.
https://en.cppreference.com/w/cpp/chrono
Yeah, it is a bit chaotic.
...but, given that there often isn't just one "a time point from the OS", and thinking about the difference clock types on Linux (CLOCK_REALTIME, CLOCK_MONOTONIC, CLOCK_BOOTTIME, etc...[0]), clocks and calendars are just messy. If you try and simplify them, you miss some edge cases which always end up being important to someone.
I guess there are just a bunch of tradeoffs that need to be made, and no matter which ones anyone makes, a lot of other people would have made different ones.
[0] https://manpages.debian.org/bookworm/manpages-dev/clock_getr...
It's worth noting that GetTickCount() is documented as returning an unsigned count, and unless you really need to time intervals > ~49 days to millisecond accuracy, everything works as expected with modulo arithmetic.
Windows' AppVerifier has an option that causes GTC to rollover much sooner, specifically to test for such bugs.